RecyclerView新增Firestore数据后重复显示内容问题求助
问题:RecyclerView新增Firestore数据后出现重复内容
每当尝试新增编号时,RecyclerView列表会同时显示旧列表与新列表内容,出现重复。编号存储在Firestore中,通过Firestore获取数据展示,例如添加编号3后,列表同时显示原有内容和包含3的新内容。
数据获取代码
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(); } } }); }
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); } } }
修复方案
核心问题
addSnapshotListener是Firestore的实时监听回调,每次数据变动(包括新增、修改、删除)都会触发onEvent方法。原代码中每次回调直接执行allDataList.addAll(data),没有先清空旧数据,导致新数据追加到旧数据后,出现重复内容。同时,每次调用getAllData都重新创建allDataList和adapter,属于冗余操作。
具体修改
- 将数据列表和适配器改为类成员变量,避免重复初始化:
// 作为Activity的类成员变量 private ArrayList<TableInfo> allDataList = new ArrayList<>(); private ReadTableInfo adapter;
- 调整
getAllData方法,RecyclerView的配置只做一次,监听回调内先清空旧数据再添加新数据:
public void getAllData(){ // 初始化适配器与RecyclerView布局,仅执行一次 adapter = new ReadTableInfo(MainActivity.this, allDataList); rcv.setLayoutManager(new GridLayoutManager(MainActivity.this, 3)); rcv.setAdapter(adapter); 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 && value != null) { // 清空旧数据,再添加最新的完整数据 allDataList.clear(); List<TableInfo> data = value.toObjects(TableInfo.class); allDataList.addAll(data); // 通知适配器数据更新 adapter.notifyDataSetChanged(); } } }); }
- (可选优化)如果数据量较大,建议使用
DiffUtil替代notifyDataSetChanged,提升RecyclerView更新效率,避免全量刷新。
内容的提问来源于stack exchange,提问作者shaz_M
相关产品推荐
相关产品推荐

