Autore Topic: Eliminare item da ListView  (Letto 1788 volte)

Offline tsubaiam

  • Nuovo arrivato
  • *
  • Post: 19
  • Respect: 0
    • Mostra profilo
Eliminare item da ListView
« il: 26 Dicembre 2010, 14:12:52 CET »
0
Ciao a tutti!  :-)
Dunque, ho una ListVIew che permette il click su tutto l'item o il click su un'immagine interna all'item.
Cliccando su quest'ultima appare una dialog in cui si chiede se eliminare l'item selezionato; a quel punto io vorrei che (in caso di conferma) l'item venisse eliminato e la lista aggiornata "in tempo reale".
Ho usato il notifyDataSetChanged() ma non va...comunque, bando alle chiacchere, vi posto il codice  :-)

Codice (Java): [Seleziona]
public class BookmarkList extends ListActivity {
       
        static final int DIALOG_REMOVE_BOOKMARK = 0;
       
        Place place;
        Place[] bookmarks = {
                new Place("Posizione1", 40, 12),
                new Place("Posizione2", 41, 11),
                new Place("Posizione3", 42, 9),
                new Place("Posizione4", 39, 12),
                new Place("Posizione5", 38, 12),
                new Place("Posizione6", 42, 12),
                new Place("Posizione7", 41, 13)
                };
        ArrayAdapter<Place> arrayAdapter;
       
        @Override
        public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
       
        arrayAdapter = new ArrayAdapter<Place>(this, R.layout.bookmarkrow, R.id.bookmark, bookmarks){          
               
                @Override
                public View getView(int position, View convertView, ViewGroup parent){
                        ViewHolder viewHolder = null;
                        if(convertView == null){
                                LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                                convertView = inflater.inflate(R.layout.bookmarkrow, null);
                                viewHolder = new ViewHolder();
                                viewHolder.removeButton = (ImageView)convertView.findViewById(R.id.bookmarkRemove);
                                viewHolder.bookmark = (TextView)convertView.findViewById(R.id.bookmark);
                                convertView.setTag(viewHolder);
                        }
                        else
                                viewHolder = (ViewHolder)convertView.getTag();
                       
                        if(position != 0){
                                viewHolder.removeButton.setImageResource(R.drawable.remove_bookmark);
                                viewHolder.removeButton.setOnClickListener(new OnClickListener(){
                                public void onClick(View v){
                                        dialogRemoveBookmark(v);
                                }
                        });
                        }
                       
                        Place place = getItem(position);
                        viewHolder.bookmark.setText(place.getName());
                        viewHolder.removeButton.setTag(place);
                        return convertView;
                }
        };
       
        setListAdapter(arrayAdapter);
       
        getListView().setOnItemClickListener(new OnItemClickListener(){
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                        Place place = (Place)parent.getItemAtPosition(position);
                Log.i("CLICK", position + " " + place.getName());
            }
        });
    }
       
        private void dialogRemoveBookmark(View v){
               
                place = (Place)v.getTag();
                showDialog(DIALOG_REMOVE_BOOKMARK);
        }
       
        @Override
        protected Dialog onCreateDialog(int id){
                Dialog dialog;
            switch(id) {
            case DIALOG_REMOVE_BOOKMARK:
                return createDialogRemoveBookmark();
            default:
                dialog = null;
            }
            return dialog;
        }
       
        @Override
        protected void onPrepareDialog(int id, Dialog dialog){
            switch(id) {
            case DIALOG_REMOVE_BOOKMARK:
                dialog = prepareDialogRemoveBookmark(dialog);
            default:
                dialog = null;
            }
        }
       
        private Dialog createDialogRemoveBookmark(){
               
                AlertDialog.Builder builder = new AlertDialog.Builder(this);
                builder.setTitle("Elimina preferito")
                           .setMessage("Sei sicuro di voler eliminare " + place.getName() + " dai preferiti?")
                       .setCancelable(false)
                       .setPositiveButton("Sì", new DialogInterface.OnClickListener() {
                           public void onClick(DialogInterface dialog, int id) {
                                removeBookmark();
                           }
                       })
                       .setNegativeButton("Annulla", new DialogInterface.OnClickListener() {
                           public void onClick(DialogInterface dialog, int id) {}
                       });
                return builder.create();
        }
       
        private Dialog prepareDialogRemoveBookmark(Dialog dialog){
                AlertDialog dialogUp = (AlertDialog)dialog;
                dialogUp.setMessage("Sei sicuro di voler eliminare " + place.getName() + " dai preferiti?");
                return dialogUp;
        }
       
        private void removeBookmark(){
                Log.i("CLICK", place.getName() + " remove");
                Place[] temp = new Place[bookmarks.length-1];
                int j = 0;
                for(int i=0; i<bookmarks.length; i++){
                        if(!(bookmarks[i].equals(place))){
                                temp[j] = bookmarks[i];
                                j++;
                        }
                }
                bookmarks = temp;
                arrayAdapter.notifyDataSetChanged();
        }
       
        private static class ViewHolder{
                public ImageView removeButton;
                public TextView bookmark;
        }
}

Sicuramente farò qualche errore grossolano (dovuto anche al fatto che non ho ancora ben capito l'utilizzo delle classi anonime in java), però non riesco a capire dov'è...
« Ultima modifica: 26 Dicembre 2010, 14:15:14 CET da tsubaiam »

Offline Ricky`

  • Amministratore
  • Utente storico
  • *****
  • Post: 3489
  • Respect: +506
    • Github
    • Google+
    • rciovati
    • Mostra profilo

Offline tsubaiam

  • Nuovo arrivato
  • *
  • Post: 19
  • Respect: 0
    • Mostra profilo
Re:Eliminare item da ListView
« Risposta #2 il: 26 Dicembre 2010, 15:46:48 CET »
0
ho provato ad aggiungerlo alla funzione removeBookmark() così:
Codice (Java): [Seleziona]
bookmarks = temp;
arrayAdapter.remove(place);
arrayAdapter.notifyDataSetChanged();
ma dà eccezione: java.lang.UnsupportedOperationException.

Offline Ricky`

  • Amministratore
  • Utente storico
  • *****
  • Post: 3489
  • Respect: +506
    • Github
    • Google+
    • rciovati
    • Mostra profilo
Re:Eliminare item da ListView
« Risposta #3 il: 26 Dicembre 2010, 16:16:58 CET »
0
giusto per curiosità, proveresti a cambiare da array ad ArrayList?

Offline tsubaiam

  • Nuovo arrivato
  • *
  • Post: 19
  • Respect: 0
    • Mostra profilo
Re:Eliminare item da ListView
« Risposta #4 il: 26 Dicembre 2010, 16:46:07 CET »
0
Con l'ArrayList funziona!  :-) senza necessità di applicare il metodo remove all'adapter.
E' bastato mettere al posto di tutta la pappardella per eliminare un elemnto dall'array:
Codice (Java): [Seleziona]
bookmarksList.remove(place);
arrayAdapter.notifyDataSetChanged();

C'è solo un comportamento "anomalo" che non mi so spiegare: nell'override del metodo getView all'inizio metto:
Codice (Java): [Seleziona]
if(position != 0){
        viewHolder.removeButton.setImageResource(R.drawable.remove_bookmark);
        viewHolder.removeButton.setOnClickListener(new OnClickListener(){
        public void onClick(View v){
             dialogRemoveBookmark(v);
        }
        });
}
perché voglio che non ci sia la possibiltà di eliminare l'item in prima posizione, quindi voglio che non venga visualizzata l'immagine e che non ci sia il listener.
Alla prima visualizzazione della lista funziona tutto correttamente, però se elimino un item mi visualizza la lista con l'immagine ed il listener anche per l'item in prima posizione  :-o
« Ultima modifica: 26 Dicembre 2010, 16:47:48 CET da tsubaiam »

Offline Ricky`

  • Amministratore
  • Utente storico
  • *****
  • Post: 3489
  • Respect: +506
    • Github
    • Google+
    • rciovati
    • Mostra profilo
Re:Eliminare item da ListView
« Risposta #5 il: 26 Dicembre 2010, 16:51:56 CET »
0
Usando il riciclo delle view devi inizializzare complemamente le view.
Codice (Java): [Seleziona]
if(position != 0){
        viewHolder.removeButton.setVisibility(View.VISIBLE);
        //L'img di sotto puoi metterla direttamente nell'xml direi.
        viewHolder.removeButton.setImageResource(R.drawable.remove_bookmark);
        viewHolder.removeButton.setOnClickListener(new OnClickListener(){
                public void onClick(View v){
                                dialogRemoveBookmark(v);
                }}
        );
}else{
        viewHolder.removeButton.setVisibility(View.GONE);
}

Offline tsubaiam

  • Nuovo arrivato
  • *
  • Post: 19
  • Respect: 0
    • Mostra profilo
Re:Eliminare item da ListView
« Risposta #6 il: 26 Dicembre 2010, 17:11:40 CET »
0
Ho fatto come hai suggerito ed ho ottenuto questo comportamento "paranormale":
- alla prima visualizzazione tutto ok
- elimino un item qualsiasi: scompare l'immagine dall'item in ultima posizione, tutte le altre ci sono (compreso l'item in prima posizione)
- elimino un altro item qualsiasi: scompare l'immagine dall'item in prima posizione, tutte le altre ci sono (ricompare anche l'immagine in ultima posizione che prima era scomparsa)
- elimino un altro item qualsiasi: tutti gli item hanno l'immagine (compreso il primo).
Alle successive eliminazioni tutti gli item mantengono l'immagine...

Veramente strano  o_O

Offline Ricky`

  • Amministratore
  • Utente storico
  • *****
  • Post: 3489
  • Respect: +506
    • Github
    • Google+
    • rciovati
    • Mostra profilo
Re:Eliminare item da ListView
« Risposta #7 il: 26 Dicembre 2010, 17:20:06 CET »
0
Metti un po' di tracciamenti per capire cosa succede...

Offline tsubaiam

  • Nuovo arrivato
  • *
  • Post: 19
  • Respect: 0
    • Mostra profilo
Re:Eliminare item da ListView
« Risposta #8 il: 26 Dicembre 2010, 18:26:36 CET »
0
Ho provato a fare un po' di stampe di controllo (anche per vedere se in qualche modo in seguito ad un'eliminazione si sballasse l'indice position della lista), ma niente da fare.
Posto comunque un po' di screenshot per spiegarmi meglio su cosa succede.

Prima schermata:Dopo eliminazione Posizione3
Dopo eliminazione Posizione5Dopo eliminazione Posizione7

Nota: non so se può essere utile, ma nella funzione removeBookmark() se provo a richiamare nuovamente il metodo setListAdapter(arrayAdapter) al posto di arrayAdapter.notifyDataSetChanged() l'aggiornamento della lista in seguito all'eliminazione di un item avviene correttamente...io però volevo farlo funzionare con il secondo metodo  :-)
« Ultima modifica: 26 Dicembre 2010, 18:31:11 CET da tsubaiam »

Offline Ricky`

  • Amministratore
  • Utente storico
  • *****
  • Post: 3489
  • Respect: +506
    • Github
    • Google+
    • rciovati
    • Mostra profilo
Re:Eliminare item da ListView
« Risposta #9 il: 26 Dicembre 2010, 19:17:32 CET »
0
Hai messo dei tracciamenti nel metodo getView per vedere un pochino lo stack delle chiamate a tale metodo? Magari scopri qualcosa di utile.
Comunque io se fossi in te andrei direttamente a rimuovere l'item dall'adapter. Se fai in quel modo non c'è neanche bisogno di fare il notifyDataSetChanged() perchè lo chiama automaticamente.

Offline tsubaiam

  • Nuovo arrivato
  • *
  • Post: 19
  • Respect: 0
    • Mostra profilo
Re:Eliminare item da ListView
« Risposta #10 il: 26 Dicembre 2010, 19:33:58 CET »
0
Sì, ho messo un po' di "Log.i(tag, string)" nel metodo getView, ma per il momento non sono riuscito ancora a scoprire niente di interessante.
Sicuramente il problema sta lì perché ho notato dei comportamenti anomali nella comparsa/scomparsa della X rossa anche se faccio scorrere la lista in alto e in basso.
Sembra che l'immagine compaia e scompaia quando gli pare!   :-o