colletjb
colletjb

Reputation: 75

How to manage deleting an item on a CursorAdapter

I'm currently facing a stupid issue. I've a listview with a custom adapter (extending CursorAdapter).

It displays a custom view with different buttons (share, like, delete). For the delete button, it has an alertdialog to confirm the removal of the item. When the user confirms, the item is deleted from the db. Everything works fine until here.

My question is, how can I update my listview efficiently with my new dataset?

Thanks a lot for your help.

Code:

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);
        (...)
    }
    (...)
}

Upvotes: 5

Views: 6776

Answers (4)

JPMagalhaes
JPMagalhaes

Reputation: 3621

If you use LoaderManager to manage the lifecycle of your cursors (that is the right way to do this) you need only to call restartLoader and then (re)set the cursor of your adapter in onLoadFinished. Your listview will be reloaded with updated data.

The management of a cursor in your activity or fragment should be done in a very simple and straightforward way:

  • In order to initialize your cursor:

    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;
    }
    
  • And then, when you need to reload your data:

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

Upvotes: 9

Steven Byle
Steven Byle

Reputation: 13269

After you delete the item in the DB, call notifyDataSetChanged on your CommentCursorAdapter, granted with this anonymous inner class you are using you will need a final reference to this since this in inside your CursorAdapter. This should trigger a refresh of your ListView.

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

Upvotes: 1

tolgap
tolgap

Reputation: 9778

Just requery the Cursor like this:

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();                                   
}   

and then call notifyDataSetChanged() to tell the Adapter that the data has changed, and it has to build the adapter again.

This will be an intense operation if the requery takes long. Consider doing it in another thread.

Upvotes: 1

Loxley
Loxley

Reputation: 1781

Call cursor.requery(); notifyDataSetChanged(); .

If you want real performance use the AsyncTaskLoader.

Upvotes: 1

Related Questions