Whenever I try to add a new number, the list will duplicate. It will show the old list and then the new list. I am storing these numbers in Firestore and from there I am retrieving them.
For example, I tried adding 3 to it. It showed the old list and then the new list.
[enter image description here](https://i.stack.imgur.com/TrvIl.png)Here is how I am retrieving data
ReadTableInfo adapter;
public void getAllData(){
allDataList = new ArrayList<>();
allDataList.clear();
adapter = new ReadTableInfo(MainActivity.this,allDataList);
db.collection("Date").document(du).collection("Table").orderBy("tableNumber").addSnapshotListener(new EventListener<QuerySnapshot>() {
@Override
public void onEvent(@Nullable QuerySnapshot value, @Nullable FirebaseFirestoreException error) {
if (error == null) {
List<TableInfo> data= value.toObjects(TableInfo.class);
allDataList.addAll(data);
rcv.setLayoutManager(new GridLayoutManager(MainActivity.this,3));
rcv.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
}
});
}
This is the adapter for RecyclerView.
public class ReadTableInfo extends RecyclerView.Adapter<ReadTableInfo.ReadTableInfoHolder> {
MainActivity mainActivity;
ArrayList<TableInfo> allDataList;
public ReadTableInfo(MainActivity mainActivity, ArrayList<TableInfo> allDataList) {
this.allDataList=allDataList;
this.mainActivity=mainActivity;
}
@NonNull
@Override
public ReadTableInfoHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new ReadTableInfoHolder(LayoutInflater.from(mainActivity).inflate(R.layout.item_table,parent,false));
}
@Override
public void onBindViewHolder(@NonNull ReadTableInfoHolder holder, int position) {
holder.itemTableNumber.setText(allDataList.get(position).getTableNumber());
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mainActivity.startActivity(new Intent(mainActivity,TableWorker.class).putExtra("key",allDataList.get(position).getUid())
.putExtra("kw2",allDataList.get(position).getKw()));
}
});
}
@Override
public int getItemCount() {
return allDataList.size();
}
class ReadTableInfoHolder extends RecyclerView.ViewHolder {
TextView itemTableNumber;
public ReadTableInfoHolder(@NonNull View itemView) {
super(itemView);
itemTableNumber=itemView.findViewById(R.id.tableNo);
}
}
}
2
Answers
This is happening because each time something inside the database takes place, for example, an addition, an update, or a delete operation, the
QuerySnapshot
contains all the data at the location the listener is pointing to. So to solve this, before adding data to the list, make sure to call the List#clear() method. In code, it will be as simple as:For your use case, ListAdapter might improve and simplify things. It will manage updating the list correctly and animate any changed (see also DiffCallback for better update handling).
ListAdapter
extendsRecyclerView.Adapter
and provides all functionality to display lists of data. When you get a new data list you just submit it to the adapter by callingadapter.submitList(dataList)
and it will calculate the difference between the previous list and new list. With this you do not have toclear()
the adapter first or callnotifyDataSetChanged()
.