Search code examples
androidfirebasefirebase-realtime-databaseswipe

ItemTouchHelper swipe to dismiss double the size of the adapter list


Hellow everyone. I have implemented a swipe to dismiss behavior on my recyclerview with ItemTouchHelper.SimpleCallback, which works very well until i delete the current card information from firebase database. If, in onSwiped overrided method, i just delete the card item from list, the behavior is normal and it s all good :

@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
    final int poz = viewHolder.getAdapterPosition();
    rentAnnounceAdapter.remove(poz);
}

but, if i remove the card info from Firebase Database, like this :

@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
    final int poz = viewHolder.getAdapterPosition();
    String ID = rentAnnounceAdapter.getList()
            .get(poz)
            .getAnnounceID();
    DatabaseReference dbRef = FirebaseDatabase.getInstance()
            .getReference();
    dbRef.child(REF_RENT)
            .child(ID)
            .removeValue();
    StorageReference ref = FirebaseStorage.getInstance()
            .getReference();
    ref.child(REF_RENT_IMAGES)
            .child(ID)
            .delete().addOnSuccessListener(new OnSuccessListener<Void>() {
        @Override
        public void onSuccess(Void aVoid) {
            rentAnnounceAdapter.remove(poz);
        }
    });
}

the data is removed from firebase database, card is removed from list, but, after the current removed element, the list without the current element is added under the removed element. I really dont get why is happening that if i remove the item from firebase, but if i dont remove from firebase all is normal

to understand better, if i have the lis

item1
item2
item3

and i remove item 3, the list displayed on screen will be

item1
item2
item1
item2

or, another example, if i remove item2, will be item1 item3 item1 item3

in my fragment, i'm attaching the ItemTouchHelper to recyclerview like this :

public void addDismissBehavior(){
    ItemTouchHelper.Callback callback = new CardSwipeItemTouchHelper(adapter);
    ItemTouchHelper helper = new ItemTouchHelper(callback);
    helper.attachToRecyclerView(rents);
}

CardSwipeItemTouchHelper class :

public class CardSwipeItemTouchHelper extends ItemTouchHelper.SimpleCallback {
private RentAnnounceAdapter rentAnnounceAdapter;

private static final String REF_RENT = "rent-announces";
private static final String REF_RENT_IMAGES = "rent-images";

public CardSwipeItemTouchHelper(RentAnnounceAdapter adapter){
    super(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT);
    this.rentAnnounceAdapter = adapter;
}


@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
    rentAnnounceAdapter.swap(viewHolder.getAdapterPosition(), target.getAdapterPosition());
    return true;
}

@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
    final int poz = viewHolder.getAdapterPosition();
    String ID = rentAnnounceAdapter.getList()
            .get(poz)
            .getAnnounceID();
    DatabaseReference dbRef = FirebaseDatabase.getInstance()
            .getReference();
    dbRef.child(REF_RENT)
            .child(ID)
            .removeValue();
    StorageReference ref = FirebaseStorage.getInstance()
            .getReference();
    ref.child(REF_RENT_IMAGES)
            .child(ID)
            .delete().addOnSuccessListener(new OnSuccessListener<Void>() {
        @Override
        public void onSuccess(Void aVoid) {
            rentAnnounceAdapter.remove(poz);
        }
    });
}

@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
    final int poz = viewHolder.getAdapterPosition();
    rentAnnounceAdapter.remove(poz);
}

}

remove and swap methods from adapter, the rest of it is basic adapter methods

public void remove(int position){
    cardRentAnnounceArrayList.remove(position);
    notifyItemRemoved(position);
}

public void swap(int fPoz, int secPoz){
    Collections.swap(cardRentAnnounceArrayList, fPoz, secPoz);
    notifyItemMoved(fPoz, secPoz);
}

If anyone have a clue with what's happening here, please tell me. Thanks.

Edit 1

After one hour of debugging i have still not found the problem. If anyone knows the answer... i m waiting for it


Solution

  • I have solved the problem. The problem was, when opening the fragment and populating the adapter with list of items from firebase, i have used reference.addValueEventListener( ... ) which was listening for every change on database, and re-changing the data when needed. So, after deleting, somehow it was adding the rest of the announces on the current list.

    using reference.addListenerForSingleValueEvent ( .. ) for downlading the list solved my problem, since is not needed to re-download and set the list after every delete, cuz it's syncronously deleted both locally and on online database.