Reputation: 325
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
Upvotes: 1
Views: 2129
Reputation: 379
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.
Upvotes: 0
Reputation: 945
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
addListenerForSingleValueEvent
.removeValue();
on the ref.null
if it is null we can now update our recyclerview
.RecyclerView
.first of all, item should be removed from the list!
mDataSet.remove(getAdapterPosition());
then:
notifyItemRemoved(getAdapterPosition());
notifyItemRangeChanged(getAdapterPosition(),mDataSet.size());
Upvotes: 2