skip to Main Content

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


  1. Whenever I try to add a new number, the list will duplicate. It will show the old list and then the new list.

    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:

    List<TableInfo> data= value.toObjects(TableInfo.class);
    if(!data.empty()) {
        allDataList.clear(); //👈
    }
    allDataList.addAll(data);
    rcv.setLayoutManager(new GridLayoutManager(MainActivity.this,3));
    rcv.setAdapter(adapter);
    adapter.notifyDataSetChanged();
    
    Login or Signup to reply.
  2. 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 extends RecyclerView.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 calling adapter.submitList(dataList) and it will calculate the difference between the previous list and new list. With this you do not have to clear() the adapter first or call notifyDataSetChanged().

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search