2013-03-05 15 views
5

Attualmente sto affrontando un problema stupido. Ho un listview con un adattatore personalizzato (estendendo CursorAdapter).Come gestire l'eliminazione di un elemento su un CursorAdapter

Visualizza una vista personalizzata con pulsanti diversi (condividi, mi piace, elimina). Per il pulsante Elimina, ha un messaggio di avviso per confermare la rimozione dell'articolo. Quando l'utente conferma, l'elemento viene cancellato dal db. Tutto funziona bene fino a qui.

La mia domanda è, come posso aggiornare la mia list list in modo efficiente con il mio nuovo set di dati?

Grazie mille per il vostro aiuto.

Codice:

public class CommentCursorAdapter extends CursorAdapter{ 
    (...) 
    @Override 
    public void bindView(View view, Context arg1, Cursor cursor) { 
    (...) 
     holder.list_item_comment_discard_btn.setOnClickListener(new OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      final String _id = v.getTag().toString(); 
      AlertDialog.Builder builder = new AlertDialog.Builder(mActivity); 
      builder.setTitle("Delete"); 
      builder.setMessage("Do you want to delete "+_id); 
      builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { 
       public void onClick(DialogInterface dialog, int id) { 
        // User clicked OK button 
        DBAdapter dba = new DBAdapter(mActivity); 
        dba.open(); 
        dba.remove(_id); 
        Log.i("TAAG", "removed: "+_id); 
        dba.close();  

       // How to update the listview ??          
       } 
      }); 
      builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { 
       public void onClick(DialogInterface dialog, int id) { 
        // User cancelled the dialog 
       } 
      }); 

      AlertDialog d = builder.create(); 
      d.show(); 
     } 
     }); 
     holder.list_item_comment_discard_btn.setTag(_id); 
     (...) 
    } 
    (...) 
} 

risposta

9

Se si utilizza LoaderManager per gestire il ciclo di vita dei cursori (che è il modo giusto per fare questo) è necessario solo per chiamare restartLoader e poi (ri) impostare il cursore della scheda in onLoadFinished. Il tuo listview sarà ricaricato con dati aggiornati.

La gestione di un cursore nella vostra attività o un frammento dovrebbe essere fatto in un modo molto semplice e diretto:

  • per inizializzare il cursore:

    public void onCreate(Bundle savedInstanceState) { // or onStart 
    // ... 
    this.getLoaderManager().initLoader(MY_CURSOR_ID, null, this); 
    // ... 
    } 
    
    public Loader<Cursor> onCreateLoader(int id, Bundle args) { 
    // TODO: create a cursor loader that will load your cursor here 
    } 
    
    public void onLoadFinished(Loader<Cursor> arg0, final Cursor arg1) { 
    // TODO: set your cursor as the cursor of your adapter here; 
    } 
    
    public void onLoaderReset(Loader<Cursor> arg0) { 
    // TODO: set null as the cursor of your adapter and 'free' all cursor 
    // references; 
    } 
    
  • E poi, quando è necessario ricaricare i dati:

    this.getLoaderManager().restartLoader(MY_CURSOR_ID, null, this); 
    
+1

ho implementato un'interfaccia sul mio adattatore per notificare l'elenco quando un elemento viene eliminato, quindi come suggerisco, riavvio il mio loader. Ora funziona ;) – colletjb

1

chiamata cursor.requery(); notifyDataSetChanged(); .

Se si desidera prestazioni reali utilizzare lo AsyncTaskLoader.

+0

è deprecato! – Online98

+0

Non funziona! :( – Jorgesys

1

Basta richiedere nuovamente l'Cursor in questo modo:

public void onClick(DialogInterface dialog, int id) { 
    // User clicked OK button 
    DBAdapter dba = new DBAdapter(mActivity); 
    dba.open(); 
    dba.remove(_id); 
    Log.i("TAAG", "removed: "+_id); 
    dba.close();  
    cursor.requery(); 
    notifyDataSetChanged();         
} 

e quindi chiamare notifyDataSetChanged() per dire al Adapter che i dati è cambiato, e deve costruire di nuovo l'adattatore.

Questa operazione sarà intensa se la richiesta richiede molto tempo. Considera di farlo in un altro thread.

+0

Ho provato, ma non ha funzionato.Inoltre, cursor.requery() è deprecato :( – colletjb

+0

Beh, se è deprecato, si potrebbe anche richiedere un nuovo cursore usando un 'AsyncTaskLoader' come @Loxley menzionato nel rispondi di seguito: – tolgap

1

Dopo aver eliminato la voce nel DB, chiami notifyDataSetChanged sul CommentCursorAdapter, concesso con questa classe interna anonima che si sta utilizzando avrete bisogno di un final riferimento a this poiché questo all'interno del vostro CursorAdapter. Questo dovrebbe innescare un aggiornamento del tuo ListView.

http://developer.android.com/reference/android/widget/BaseAdapter.html#notifyDataSetChanged()

+0

L'ho provato senza successo: '(: builder.setPositiveButton (android.R.string.ok, new DialogInterface.OnClickListener() { \t \t \t \t \t public void onClick (finestra DialogInterface, int id) { \t \t \t \t \t \t // l'utente fa clic su OK \t \t \t \t \t \t DBAdapter dba = new DBAdapter (mActivity); \t \t \t \t \t \t dba.open(); \t \t \t \t \t \t dba.remove (_id); \t \t \t \t \t \t Log.i ("TAAG", "rimosso:" + _id); \t \t \t \t \t \t dba.close(); \t \t \t \t \t \t \t \t \t \t \t \t \t \t cursor.requery(); \t \t \t \t \t \t mInstance.notifyDataSetChanged(); \t \t \t \t \t} \t \t \t \t}); – colletjb

Problemi correlati