AutoCompleteView选中项添加至RecyclerView时数据被覆盖问题求助
问题原因与解决方案
核心问题
- 数据源复用冲突:你将AutoComplete的候选产品列表与RecyclerView的已选产品列表共用了同一个
productItemsList,导致两者数据混淆,无法实现追加效果。 - 未正确更新RecyclerView数据:
addItemToRecycle方法仅重复设置适配器,没有将选中的产品添加到RecyclerView的专属数据源,也未通知适配器刷新界面。
代码修改步骤
1. 拆分数据源(NewListActivity)
新增独立的已选产品列表,与AutoComplete的候选列表分离:
// AutoComplete候选数据源 private List<ProductItem> productItemsList = new ArrayList<>(); // RecyclerView已选数据源 private List<ProductItem> selectedProductsList = new ArrayList<>();
2. 初始化RecyclerView(NewListActivity的onCreate方法)
将RecyclerView的适配器绑定到新的已选数据源,且仅设置一次适配器:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_new_list); getDataFromFire(); ac_tv_Product = findViewById(R.id.ac_tv_Product); rvShoppingList = findViewById(R.id.rvShoppingList); rvShoppingList.setLayoutManager(new LinearLayoutManager(getApplicationContext())); autoCompleteProductAdapter = new AutoCompleteProductAdapter(this, productItemsList); ac_tv_Product.setAdapter(autoCompleteProductAdapter); // 初始化RecyclerView专属数据源与适配器 recycleViewerListAdapter = new RecycleViewerListAdapter(selectedProductsList); rvShoppingList.setAdapter(recycleViewerListAdapter); // 仅设置一次 ac_tv_Product.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) { addItemToRecycle(position); } }); }
3. 修正addItemToRecycle方法(NewListActivity)
实现选中产品的追加逻辑,并通知适配器刷新:
private void addItemToRecycle(int position) { // 获取AutoComplete中选中的产品 ProductItem selectedItem = productItemsList.get(position); // 追加到已选列表 selectedProductsList.add(selectedItem); // 通知RecyclerView插入新项(比notifyDataSetChanged更高效) recycleViewerListAdapter.notifyItemInserted(selectedProductsList.size() - 1); // 清空输入框,提升交互体验 ac_tv_Product.setText(""); }
4. 完善Firebase数据加载后的适配器更新(NewListActivity的getDataFromFire方法)
Firebase异步加载数据后,通知AutoComplete适配器刷新候选列表:
private void getDataFromFire() { docRef.get() .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() { @Override public void onComplete(@NonNull Task<QuerySnapshot> task) { if (isFinishing() || isDestroyed()) return; if (task.isSuccessful()) { productItemsList.clear(); // 清空旧数据,避免重复加载 for (QueryDocumentSnapshot document : task.getResult()) { Log.d("Deu certo", document.getId() + " => " + document.getData()); String name = document.getString("name"); String local = document.getString("location"); productItemsList.add(new ProductItem(name, local)); } // 通知AutoComplete适配器更新候选列表 autoCompleteProductAdapter.notifyDataSetChanged(); } else { Log.d("deu errado", "Error getting documents: ", task.getException()); } } }); }
额外优化(可选)
在RecyclerView适配器中添加专门的添加数据方法,封装逻辑:
public class RecycleViewerListAdapter extends RecyclerView.Adapter<RecycleViewerListAdapter.ViewHolder> { List<ProductItem> items; public RecycleViewerListAdapter(List<ProductItem> items) { this.items = items; } // 新增添加数据方法 public void addItem(ProductItem item) { items.add(item); notifyItemInserted(items.size() - 1); } // 其余原有代码不变... }
之后addItemToRecycle方法可以简化为:
private void addItemToRecycle(int position) { ProductItem selectedItem = productItemsList.get(position); recycleViewerListAdapter.addItem(selectedItem); ac_tv_Product.setText(""); }
内容的提问来源于stack exchange,提问作者Pedro Tartari
相关产品推荐
相关产品推荐

