简体   繁体   中英

Update the Recycleview adapter when a value is deleted from firebase

I have used a Recycleview using cardivew with list of data and button to delete any value. when I click button it does delete the value from firebase database but still the text and row remains in adapter in app but only when i close activity by going back and reopen then row is empty.

How can I update the recycleview instantly when I hit delete button

Here is my code

 public class SubjectBooksAdapter extends RecyclerView.Adapter<SubjectBooksAdapter.MyViewHolder> { ArrayList<Books> bookslist; FirebaseDatabase database; DatabaseReference dbreference; public SubjectBooksAdapter(ArrayList<Books> bookslist){ this.bookslist = bookslist; } @Override public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout,parent,false); return new MyViewHolder(v); } public class MyViewHolder extends RecyclerView.ViewHolder { Button mSolved; MyViewHolder(final View itemView) { super(itemView); database = FirebaseDatabase.getInstance(); dbreference = database.getReference("roomrequest"); dbreference.keepSynced(true); mSolved = (Button) itemView.findViewById(R.id.book_solved); mSolved.setTransformationMethod(null); fauth = FirebaseAuth.getInstance(); } } @Override public void onBindViewHolder(final MyViewHolder holder, final int position) { database = FirebaseDatabase.getInstance(); dbreference = database.getReference("roomrequest"); holder.mSolved.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference(); DatabaseReference classicalMechanicsRef = rootRef.child("roomrequest").child("request").child(g.getRequestid()); ValueEventListener valueEventListener = new ValueEventListener() { @Override public void onDataChange(DataSnapshot dataSnapshot) { dataSnapshot.getRef().removeValue(); } @Override public void onCancelled(@NonNull DatabaseError databaseError) { } }; classicalMechanicsRef.addListenerForSingleValueEvent(valueEventListener); } }); } @Override public int getItemCount() { return bookslist.size(); } }

Any help is appreciated

classicalMechanicsRef.addListenerForSingleValueEvent(valueEventListener);

Firebase provide 3 types of listeners for events.Here you have used is a listener for single value event. If you just want to read the value once, you use ref.addListenerForSingleValueEvent() .

Here you want is updated list from firebase, what you have to do is fetch the list again from firebase and pass it to the adapter. But as it is firebase event it will obviously delete data from the firebase database so you can remove the element from your recyclerview.

Bad Approach

If multiple users are not updating the same list then you can use ValueEventListener

 reference.addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
       // set recyclverview from data
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {
       // error handling
    }
});

This approach is bad because if any other user made changes in the data then your onDataChange() will be called again and again and your list would be updated.

Good Approach

  1. Register with a addListenerForSingleValueEvent .
  2. Pass all items to recycler adapter.
  3. If item gets deleted then call removeValue(); on the ref.
  4. Again make a call on firebase to check if deleted is key is null if it is null we can now update our recyclerview .
  5. Use the below method to remove item from RecyclerView .

first of all, item should be removed from the list!

mDataSet.remove(getAdapterPosition());

then:

notifyItemRemoved(getAdapterPosition());
notifyItemRangeChanged(getAdapterPosition(),mDataSet.size());

Assuming that you have a firebase reference to the node that contains your books, say 'booksRef', and you have a model class for books, say "Book.java", and each book has a unique ID say "bookID". And inside your model class you have a book ID getter say " getBookID", now add a firebase onChildEventListener() to your booksRef like below:

    booksRef.addChildEventListener(new ChildEventListener ()  {

        @Override
        public void onChildAdded(DataSnapshot dataSnapshot, String s) {
            Book addedBook = dataSnapshot.getValue(Book.class);

            bookslist.add(addedBook);
            adapter.notifyItemInserted(bookslist.size());
        }


        @Override
        public void onChildChanged(DataSnapshot dataSnapshot, String s) {
            Book changedBook = dataSnapshot.getValue(Book.class);

            for (int i = 0; i < bookslist.size(); i++) {
                if (bookslist.get(i).getBookID().equals(changedBook.getBookID())) {
                    bookslist.set(i, changedBook);
                    adapter.notifyItemChanged(i);
                    break;
                }
            }
        }


        @Override
        public void onChildRemoved(DataSnapshot dataSnapshot) {
            Book removedBook = dataSnapshot.getValue(Book.class);

            for (int i = 0; i < bookslist.size(); i++) {
                if (bookslist.get(i).getBookID().equals(removedBook.getBookID())) {
                    bookslist.remove(i);
                    adapter.notifyItemRemoved(i);
                    break;
                }
            }

        }

        @Override
        public void onChildMoved(DataSnapshot dataSnapshot, String s) {

        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });

This will update the recycleview instantly after successful firebase childNode added, edited and deleted.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM