Confirmation and undo removing in RecyclerView

后端 未结 4 2034
粉色の甜心
粉色の甜心 2020-12-24 12:22

I have got a list of simple items in RecyclerView. Using ItemTouchHelper it was very easy to implement \"swipe-to-delete\" behavior.

public class TripsAdapte         


        
4条回答
  •  余生分开走
    2020-12-24 13:18

    I tried JirkaV's solution, but it was throwing an IndexOutOfBoundsException. I was able to modify his solution to work for me. Please try it and let me know if you run into problems.

     @Override
        public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
            final int adapterPosition = viewHolder.getAdapterPosition();
            final BookItem bookItem = mBookItems.get(adapterPosition); //mBookItems is an arraylist of mBookAdpater;
            snackbar = Snackbar
                    .make(mRecyclerView, R.string.item_removed, Snackbar.LENGTH_LONG)
                    .setAction(R.string.undo, new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            mBookItems.add(adapterPosition, bookItem);
                            mBookAdapter.notifyItemInserted(adapterPosition); //mBookAdapter is my Adapter class
                            mRecyclerView.scrollToPosition(adapterPosition);
                        }
                    })
                    .setCallback(new Snackbar.Callback() {
                        @Override
                        public void onDismissed(Snackbar snackbar, int event) {
                            super.onDismissed(snackbar, event);
                            Log.d(TAG, "SnackBar dismissed");
                            if (event != DISMISS_EVENT_ACTION) {
                                Log.d(TAG, "SnackBar not dismissed by click event");
                                //In my case I doing a database transaction. The items are only deleted from the database if the snackbar is not dismissed by click the UNDO button
    
                                mDatabase = mBookHelper.getWritableDatabase();
    
                                String whereClause = "_id" + "=?";
                                String[] whereArgs = new String[]{
                                        String.valueOf(bookItem.getDatabaseId())
                                };
                                mDatabase.delete(BookDbSchema.BookEntry.NAME, whereClause, whereArgs);
                                mDatabase.close();
                            }
                        }
                    });
            snackbar.show();
            mBookItems.remove(adapterPosition);
            mBookAdapter.notifyItemRemoved(adapterPosition);
        }
    

    How it works

    When the user swipes, a snackbar is shown and the item is removed from the dataset, hence this:

    snackbar.show();
    BookItems.remove(adapterPosition);
    mBookAdapter.notifyItemRemoved(adapterPosition);
    

    Since the data used in populating the recyclerView is from an SQL database, the swiped item is not removed from the database at this point.

    When the user clicks on the "UNDO" button, the swiped item is simply brought back and the recyclerView scrolls to the position of the just re-added item. Hence this:

     mBookItems.add(adapterPosition, bookItem);
     mBookAdapter.notifyItemInserted(adapterPosition); 
     mRecyclerView.scrollToPosition(adapterPosition);
    

    Then when the snackbar dismisses, I checked if the snackbar was dismissed by the user clicking on the "UNDO" button. If no, I delete the item from the database at this point.

    Probably there are performance issues with this solution, I haven''t found any. Please if you notice any, drop your comment.

提交回复
热议问题