• After 15+ years, we've made a big change: Android Forums is now Early Bird Club. Learn more here.

Delete and undo in RecyclerView causes multiple entries

Lalox3

Lurker
Apr 20, 2019
9
0
have data in my SQLite Database which I load into a RecyclerView. With an ItemTouchHelper you can delete a item and a Snackbar appears with an undo .action.



The problem I have is that when I delete and undo multiple times and I reload the app, I have got multiple entries where I deleted and restored.

I have figured out that "
pocketItemAdapter.removeItem(viewHolder.getAdapterPosition())" do not return 1 so its failing. But is that a problem with Adapter or with SQLite?


As you can see here:

ItemTouchHelper
Java:
    // Delete and undo pocket items
ItemTouchHelper.SimpleCallback recyclerviewSwipe = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT) {
    @Override
    public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
        return false;
    }

    @Override
    public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
        final Pocket pocketList = PocketItems.get(viewHolder.getAdapterPosition());
        final int deletetIndex = viewHolder.getAdapterPosition();

        pocketItemAdapter.removeItem(viewHolder.getAdapterPosition());


        if(pocketItemAdapter.getItemCount() != 0){
            textView_placeholder_recyclerview.setVisibility(View.GONE);
            imageView_placeholder_recyclerview.setVisibility(View.GONE);
        }else{
            textView_placeholder_recyclerview.setVisibility(View.VISIBLE);
            imageView_placeholder_recyclerview.setVisibility(View.VISIBLE);
        }

        Snackbar snackbar = Snackbar.make(coordinatorLayoutPocketMain,R.string.successfully_deleted,3000)
                .setAction(R.string.undo, new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        pocketItemAdapter.restoreItem(pocketList,deletetIndex);
                        database.createpocketEntry(pocketList.getTIMESTAMP(),pocketList.getAMOUNT(),pocketList.getDESCRIPTION(),pocketList.getCATEGORY());
                    }
                });
        snackbar.getView().setBackgroundColor(ContextCompat.getColor(PocketMain.this,R.color.colorBright));

        snackbar.show();
    }

RecyclerView Adapter

Java:
void removeItem(int position){
    Database database = new Database(context);
    database.deletepocketEntry(Integer.parseInt(pocketItems.get(position).getROWID()));
    pocketItems.remove(position);
    notifyItemRemoved(position);


}

void restoreItem(Pocket item, int position){
    pocketItems.add(position,item);
    notifyItemInserted(position);
    Log.d("RESTORED","restoreItem()");
}

SQLite open helper
Java:
  Integer deletepocketEntry(Integer rowID){
        SQLiteDatabase database = this.getWritableDatabase();
        Log.d("RESTORED","deletePocketEntry");
        return database.delete(KEY_DATABASE_TABLE,"rowid = ?", new String[]{Integer.toString(rowID)});
}

long createpocketEntry(String timestamp,String amount,String description, String category){
    SQLiteDatabase database = this.getWritableDatabase();
    ContentValues pocketValues = new ContentValues();
    pocketValues.put(KEY_TIMESTAMP,timestamp);
    pocketValues.put(KEY_AMOUNT,amount);
    pocketValues.put(KEY_DESCRIPTION,description);
    pocketValues.put(KEY_CATEGORY,category);
    Log.d("RESTORED","createPocketEntry");
    return database.insert(KEY_DATABASE_TABLE,null,pocketValues);
}
 


So basicly I changed something.
This should return 1 but it doesn't and I think this is the problem.
Java:
    int removeItem(int position){
        Database database = new Database(context);
        int boo = database.deletepocketEntry(Integer.parseInt(pocketItems.get(position).getROWID()));
        pocketItems.remove(position);
        notifyItemRemoved(position);
        return boo;
    }

And deletePocketEntry is:
Java:
    Integer deletepocketEntry(Integer rowID){
        SQLiteDatabase database = this.getWritableDatabase();
        return database.delete(KEY_DATABASE_TABLE,"rowid = ?", new String[]{Integer.toString(rowID)});
    }

So everytime the red snackbar appears it's because of this because it return 0 instead of 1:
Java:
if(pocketItemAdapter.removeItem(viewHolder.getAdapterPosition()) == 1){
                      

                        Snackbar snackbar = Snackbar.make(coordinatorLayoutPocketMain,R.string.successfully_deleted,3000)
                                .setAction(R.string.undo, new View.OnClickListener() {
                                    @Override
                                    public void onClick(View view) {
                                        pocketItemAdapter.restoreItem(pocketList,deletetIndex);
                                        database.createpocketEntry(pocketList.getTIMESTAMP(),pocketList.getAMOUNT(),pocketList.getDESCRIPTION(),pocketList.getCATEGORY());
                                    }
                                });
                        snackbar.getView().setBackgroundColor(ContextCompat.getColor(PocketMain.this,R.color.colorBright));

                        snackbar.show();
                    }else{

                        final Snackbar snackbar = Snackbar.make(coordinatorLayoutPocketMain,"Löschen war nicht erfolgreich",Snackbar.LENGTH_SHORT);
                                snackbar.setAction("Ok", new View.OnClickListener() {
                                    @Override
                                    public void onClick(View view) {
                                        snackbar.dismiss();
                                    }
                                });
                        snackbar.getView().setBackgroundColor(ContextCompat.getColor(PocketMain.this,R.color.red));
                        snackbar.show();
                        pocketItemAdapter.restoreItem(pocketList,deletetIndex);

                    }
 
Upvote 0
Time to get into debugging your app because this is a difficult one to answer just by static analysis of your code.
In particular I'd be interested to know what's happening in restoreItem, and the objects stored in pocketItems.
So run your app in debug mode, and trace through what's happening by setting breakpoints at crucial points in your code.
 
Upvote 0
Time to get into debugging your app because this is a difficult one to answer just by static analysis of your code.
In particular I'd be interested to know what's happening in restoreItem, and the objects stored in pocketItems.
So run your app in debug mode, and trace through what's happening by setting breakpoints at crucial points in your code.
Okay let me figure out a bit how debbuging works ^^
 
Upvote 0
Time to get into debugging your app because this is a difficult one to answer just by static analysis of your code.
In particular I'd be interested to know what's happening in restoreItem, and the objects stored in pocketItems.
So run your app in debug mode, and trace through what's happening by setting breakpoints at crucial points in your code.

Ehm at the breakpoint at restoreItem it looks like this:looks fine for me it was 3 items before
Xm94TKA.jpg
 
Last edited:
Upvote 0

BEST TECH IN 2023

We've been tracking upcoming products and ranking the best tech since 2007. Thanks for trusting our opinion: we get rewarded through affiliate links that earn us a commission and we invite you to learn more about us.

Smartphones