Fragment中两个RecyclerView适配器间如何传递选中列表数据
两个RecyclerView跨适配器传入选中商品实现方案
不要让两个适配器直接持有对方引用做数据传递,耦合度高还容易引发内存泄漏,通过上层宿主(承载页面的Fragment/Activity)做数据中转是最稳定的实现方式,按以下步骤修改即可:
1. 改造商品列表适配器FruitItemAdapter,增加加购交互回调
你当前的适配器还没有用户选中商品的交互入口,先补两个逻辑:
- 首先在
fruits_item.xml布局里加一个「加入购物车」的按钮/图标控件,给id设为btn_add_cart - 在适配器内部定义加购事件回调,把用户选中的商品回传给上层宿主:
// 写在FruitItemAdapter类内部 public interface OnAddCartListener { void onItemAdd(FruitItem selectedItem); } private OnAddCartListener addCartListener; // 对外暴露设置监听的方法 public void setOnAddCartListener(OnAddCartListener listener) { this.addCartListener = listener; }
- 在
viewHolder里补全新增按钮的控件绑定:
// 在viewHolder构造方法里加 btn_add_cart = itemView.findViewById(R.id.btn_add_cart); // 同时在viewHolder类里声明对应控件:private ImageView/Button btn_add_cart;
- 在
onBindViewHolder方法里给加购按钮绑定点击事件,触发回调:
holder.btn_add_cart.setOnClickListener(v -> { if (addCartListener != null) { addCartListener.onItemAdd(data_position); } });
2. 在宿主层维护购物车数据源,做中转
在承载两个列表的Fragment(如果水果列表和购物车分属两个不同Fragment,就用二者共同关联的Activity做宿主)里,单独维护购物车专属的数据源集合:
// 宿主页面内声明 ArrayList<FruitItem> cartList = new ArrayList<>(); // 提前初始化好购物车适配器,传空的cartList进去就行 Basket_Adapter basketAdapter = new Basket_Adapter(requireContext(), cartList);
给水果列表适配器设置加购监听,收到用户选中的商品时更新购物车数据源,再通知购物车适配器刷新:
fruitItemAdapter.setOnAddCartListener(selectedItem -> { // 先判重,避免同一个商品重复加入购物车,你可以换成自己商品的唯一id做判断 boolean hasAdded = false; for (FruitItem item : cartList) { if (item.getFruit_name().equals(selectedItem.getFruit_name())) { hasAdded = true; break; } } if (!hasAdded) { cartList.add(selectedItem); // 刷新购物车列表 basketAdapter.setfruitItem(cartList); basketAdapter.notifyDataSetChanged(); } });
3. 复杂场景可选优化方案
如果你的页面层级比较复杂(比如水果列表、购物车分属多个嵌套Fragment、跨多个页面),可以用共享ViewModel存储购物车数据源,两个列表的适配器分别通过宿主页面观察ViewModel里的购物车数据变化,自动触发刷新,不用手动写接口回调,代码维护性更高。
注意:不要尝试在FruitItemAdapter里直接持有Basket_Adapter的实例做数据更新,会导致两个适配器强耦合,后续修改商品项结构、调整页面位置时需要改动大量代码,还容易因为引用持有不当造成内存泄漏。
内容的提问来源于stack exchange,提问作者Ismail Hamzeh
相关产品推荐
相关产品推荐

