You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在两个搭载RecyclerView的Fragment间传递数据并更新购物车列表

问题排查与修复方案

你现有代码存在4个核心错误:

    1. CartRecyclerAdapter 数据更新逻辑错误
      你的SubmitItem方法中调用Items.toMutableList().add(Item),toMutableList()会生成一个全新的临时集合,添加操作是作用在这个临时对象上的,类内原本的Items集合完全没有被修改,所以getItemCount永远返回0,自然不会渲染任何条目。而且就算修改了数据,也没有调用RecyclerView的刷新通知方法,UI不会同步更新。
    1. 适配器实例不统一
      你在ItemRecyclerAdapter中调用SubmitItem的CartAdapter是你自己新建的实例,和Cart Fragment中绑定购物车RecyclerView的CartRecyclerAdapter实例完全是两个独立的对象,数据不互通,你加在新实例里的数据永远不会被购物车页面的RecyclerView读取到。
    1. 跨Fragment直接调用逻辑不符合安卓规范
      两个Fragment之间默认不能直接通信,直接持有对方适配器的引用容易引发内存泄漏、空指针等问题,官方推荐通过共享ViewModel或者宿主Activity做中转。
    1. ViewHolder引用错误
      你的CartRecyclerAdapter中onCreateViewHolder返回的是ItemRecyclerAdapter.ItemViewHolder,但你自己已经定义了CartRecyclerAdapter专属的ItemViewHolder,两个ViewHolder绑定的布局不一样,就算有数据也会显示异常甚至崩溃。

修复步骤

步骤1:修复CartRecyclerAdapter的逻辑

class CartRecyclerAdapter : RecyclerView.Adapter<CartRecyclerAdapter.ItemViewHolder>() {
    // 改用MutableList支持数据修改
    private val items = mutableListOf<ItemPost>()

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder {
        // 返回自己的ViewHolder,不要用商品列表的
        return ItemViewHolder(
            LayoutInflater.from(parent.context)
                .inflate(R.layout.layout_item_cart_list, parent, false)
        )
    }

    override fun onBindViewHolder(holder: ItemViewHolder, position: Int) {
        holder.bind(items[position])
    }

    override fun getItemCount(): Int = items.size

    fun submitItem(item: ItemPost) {
        items.add(item)
        // 通知RecyclerView插入了新条目,刷新UI
        notifyItemInserted(items.size - 1)
    }

    // 新增批量更新数据的方法,后面配合ViewModel用
    fun submitList(newList: List<ItemPost>) {
        items.clear()
        items.addAll(newList)
        notifyDataSetChanged()
    }

    class ItemViewHolder constructor(itemView: View): RecyclerView.ViewHolder(itemView) {
        val itemImage: ImageView = itemView.Item_image_cart
        val itemTitle: TextView = itemView.Item_title_cart
        val itemCategory: TextView = itemView.Item_category_cart
        val itemPrice: TextView = itemView.Item_price_cart

        fun bind(itemPost: ItemPost) {
            itemTitle.text = itemPost.Itemtitle
            itemCategory.text = itemPost.ItemCategory
            itemPrice.text = itemPost.ItemPrice
            val requestOptions = RequestOptions()
                .placeholder(R.drawable.ic_baseline_brush_24)
                .error(R.drawable.ic_baseline_brush_24)

            Glide.with(itemView.context)
                .applyDefaultRequestOptions(requestOptions)
                .load(itemPost.image)
                .into(itemImage)
        }
    }
}

步骤2:创建共享ViewModel存储购物车数据

新建CartViewModel.kt,和宿主Activity绑定,两个Fragment都可以访问同一个实例:

import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.example.karawapplication.models.ItemPost

class CartViewModel : ViewModel() {
    // 用LiveData存放购物车列表,支持数据变化监听
    val cartItemList = MutableLiveData<MutableList<ItemPost>>(mutableListOf())

    fun addItemToCart(item: ItemPost) {
        val currentList = cartItemList.value ?: mutableListOf()
        currentList.add(item)
        cartItemList.postValue(currentList)
    }
}

步骤3:修改商品列表侧的添加逻辑

首先修改ItemRecyclerAdapter,把点击事件回调到Shop Fragment,不要直接操作Cart的适配器:

// 在ItemRecyclerAdapter类内加个点击回调接口
var onItemAddClick: ((ItemPost) -> Unit)? = null

// 原来的点击事件改成回调
ItemButton.setOnClickListener {
    Toast.makeText(itemView.context, "${itempost.image}, ${itempost.Itemtitle}, ${itempost.ItemPrice}", Toast.LENGTH_SHORT).show()
    onItemAddClick?.invoke(itempost)
}

然后在Shop Fragment中初始化适配器的时候设置回调,获取ViewModel实例调用添加方法:

import androidx.fragment.app.activityViewModels

class Shop : Fragment(){
    // 获取和Activity绑定的CartViewModel实例,和Cart Fragment拿到的是同一个
    private val cartViewModel: CartViewModel by activityViewModels()
    private lateinit var itemAdapter : ItemRecyclerAdapter

    // ... 保留其他原有代码 ...

    private fun initRecyclerView() {
        ShopRecycleView.layoutManager = LinearLayoutManager(activity)
        itemAdapter = ItemRecyclerAdapter()
        // 设置添加商品的点击回调
        itemAdapter.onItemAddClick = { item ->
            cartViewModel.addItemToCart(item)
            Toast.makeText(context, "已添加到购物车", Toast.LENGTH_SHORT).show()
        }
        ShopRecycleView.adapter = itemAdapter
    }
}

如果你的项目没有引入lifecycle-livedata-ktx和lifecycle-viewmodel-ktx依赖,把by activityViewModels()换成下面的写法即可:

private val cartViewModel by lazy {
    ViewModelProvider(requireActivity())[CartViewModel::class.java]
}

步骤4:修改Cart Fragment,监听购物车数据变化更新UI

import androidx.fragment.app.activityViewModels

class Cart : Fragment() {
    private val cartViewModel: CartViewModel by activityViewModels()
    private lateinit var cartAdapter: CartRecyclerAdapter

    // ... 保留其他原有代码 ...

    private fun initRecyclerView() {
        Cart_RecyclerView.layoutManager = LinearLayoutManager(activity)
        cartAdapter = CartRecyclerAdapter()
        Cart_RecyclerView.adapter = cartAdapter

        // 监听购物车列表变化,自动更新适配器数据
        cartViewModel.cartItemList.observe(viewLifecycleOwner) { cartList ->
            cartAdapter.submitList(cartList)
        }
    }
}

内容的提问来源于stack exchange,提问作者Apprent1ce

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 02:36:04