3

I am trying to get the swipe-to-delete feature in my recyclerview. I am using onSwiped() method of ItemTouchHelper.SimpleCallback.
I get the swipe animation, and the swiped row collapses, when I use adapter.notifyItemRemoved() method. I checked the row data gets deleted from database. But, the deleted row again is regenerated and displayed on the recyclerview at the same position.

  @Override
  public void onSwiped(RecyclerView.ViewHolder viewHolder, int swipeDir) {

         ListOfItemsRecyclerViewCursorAdapter adapter = (ListOfItemsRecyclerViewCursorAdapter) rv.getAdapter();

         int position = viewHolder.getAdapterPosition();
         long itemIdToBeRemoved = rv.getAdapter().getItemId(position);

         //Deletes the item from sqlite database
         mDBManager.deleteItem(itemIdToBeRemoved);      

         adapter.notifyItemRemoved(position);

         // Using notifyItemRangeChanged, the swiped row does not collapse, but stays as a blank row.
         adapter.notifyItemRangeChanged(position, adapter.getItemCount());

         //adapter.notifyDataSetChanged();
         //Tried the following - but did not work
         //getLoaderManager().initLoader(1, null, ListOfItemsFragment.this);

        }

Seeing a few other SO questions, I tried to use adapter.notifyItemRangeChanged() method, but that stops the collapsing animation of the row, and just leaves a blank row. Blank row on swipe

I am using a Loader to load the cursor for the adapter from SQLite database. So I also tried to call initloader() method, but that also did not work.

Could you please help me solve this problem. I have tried searching for the solution on Stack Overflow but have not been able to solve the problem.

Thanks

T D Nguyen
  • 7,054
  • 4
  • 51
  • 71
sofan
  • 31
  • 1
  • 4
  • How do you populate your `RecyclerView`? I can imagine that your data is still in the used list. – yennsarah Mar 22 '16 at 08:33
  • I am populating the RecyclerView with data from SQLite database, using a custom cursor RecyclerView adapter. The cursor is loaded using a loader. Yes, it looks like the dataset is not updating. I don't understand what is causing it. – sofan Mar 22 '16 at 14:47

3 Answers3

1

I assume you have some sort of list of data inside your adapter. If yes, delete the item on the corresponding position of the deleted row.

Also, try to call viewHolder.setIsRecyclable(false);

Your onSwiped should somehow look like this:

@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
                    // your original stuff here, db deletion etc.
                    // don't forget to delete the data inside the adapter
                    viewHolder.setIsRecyclable(false);
                    adapter.notifyItemRemoved(pos);
                }

According to your comment, you are using this adapter? If so, I think you also need to call swapCursor or changeCursor. Have you seen this question?

Also, in your question, you are also using adapter.notifyItemRangeChanged, adapter.notifyItemRemoved should be enough.

Community
  • 1
  • 1
hehe
  • 1,294
  • 13
  • 26
  • I don't have any list in the adapter, I am getting the data from a cursor. I thought notifyItemRemoved() was to remove the item from the adapter. How do I remove item from the cursor? Do I have to load the cursor again? – sofan Mar 22 '16 at 16:57
  • @sofan cursor itself doesn't have data, it is just a pointer to your database. Have you tried `setIsRecyclable` and `notifyItemRemoved`? – hehe Mar 23 '16 at 01:35
  • I did try..but I still get a blank row on swipe. It doesn't collapse the row. I am using the cursor adapter from [link]https://gist.github.com/quanturium/46541c81aae2a916e31d . I am wondering if there is something different I need to do to use this adapter. – sofan Mar 23 '16 at 02:24
  • Earlier, I had tried using swapCursor() in onLoadFinished() callback method. It had not worked. But, that you mentioned it, I looked into it again. And, I was able to solve my problem. I had not overridden the swapCursor() method in my subclass of the adapter to swap the instance variable holding the cursor. To load the updated cursor, I called loader's onContentChanged() method, after deleting the item from database, in onSwiped() method. Interestingly, I didnt need to use any of the notifyItem...() methods. I hope this is the right way to solve it. Thanks for the help. – sofan Mar 24 '16 at 00:36
1

Use

adapter.remove(viewHolder.getAdapterPosition());

@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
     // delete your da entry then...
 
     Toast.makeText(activity, message, Toast.LENGTH_SHORT).show();
     adapter.remove(viewHolder.getAdapterPosition());
    
     // if I emptied the entire list...draw background 
     if( adapter.getItemCount()==0 ){
          SwipeRefreshLayout refresh = (SwipeRefreshLayout) activity.findViewById(R.id.container);
          refresh.setBackground( ContextCompat.getDrawable(activity, R.drawable.background_null) );
     }
}
AmrDeveloper
  • 3,826
  • 1
  • 21
  • 30
marco
  • 3,193
  • 4
  • 28
  • 51
  • how do I write the remove(int position) method for an adapter using cursor? I also want the collapsing animation, so I guess I ll have to call notifyItemRemoved() also. – sofan Mar 22 '16 at 17:02
  • I cannot edit property my answer now, but in OnSwipe you have to do something with your data entry. The animations will still there – marco Mar 22 '16 at 17:17
0

You can see this example at github:

https://github.com/nemanja-kovacevic/recycler-view-swipe-to-delete

dpulgarin
  • 556
  • 5
  • 17