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

如何实现嵌套RecyclerView中仅重绘点击的卡片?

解决方案

核心思路

拆分父、子RecyclerView的更新逻辑:父级仅关注分类本身的变化,子级独立处理商品数量更新,避免父级刷新导致子RecyclerView整体重绘。

步骤1:修正父级DiffUtil.ItemCallback

让父级的areContentsTheSame只比较分类自身属性(如ID、名称),不涉及子商品的数量变化。这样商品数量更新时,父级不会判定整个分类项内容变化,也就不会重绘父item及嵌套的子RecyclerView。

修改后的父级DiffUtil代码:

object ListDiffCallback : DiffUtil.ItemCallback<CategoryWithItems>() {
    override fun areItemsTheSame(oldItem: CategoryWithItems, newItem: CategoryWithItems): Boolean {
        // 优先用分类唯一ID判断,避免名称重复导致识别错误
        return oldItem.category.id == newItem.category.id
    }

    override fun areContentsTheSame(oldItem: CategoryWithItems, newItem: CategoryWithItems): Boolean {
        // 仅比较分类本身的属性,不遍历子商品数量
        return oldItem.category.name == newItem.category.name
        // 若分类有其他展示属性(如描述),可在此补充比较
    }
}

步骤2:子RecyclerView的DiffUtil独立处理数量变化

给子商品的ListAdapter编写专属DiffUtil,精准识别单个商品的数量变化,仅重绘对应的卡片:

object ItemDiffCallback : DiffUtil.ItemCallback<ItemQuantity>() {
    override fun areItemsTheSame(oldItem: ItemQuantity, newItem: ItemQuantity): Boolean {
        return oldItem.item.id == newItem.item.id
    }

    override fun areContentsTheSame(oldItem: ItemQuantity, newItem: ItemQuantity): Boolean {
        // 比较商品数量及其他需要展示的属性
        return oldItem.item.quantity == newItem.item.quantity 
                && oldItem.item.name == newItem.item.name
                // 其他商品属性(如价格)按需添加比较
    }
}

步骤3:父ViewHolder复用子Adapter

在父ViewHolder初始化时一次性设置子RecyclerView的Adapter和布局管理器,后续绑定分类数据时仅更新子Adapter的数据源,避免每次绑定都重建子RecyclerView:

class CategoryViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
    private val childAdapter = ItemListAdapter(ItemDiffCallback)
    private val childRecyclerView: RecyclerView = itemView.findViewById(R.id.child_recycler)

    init {
        // 仅初始化一次子RecyclerView的配置
        childRecyclerView.adapter = childAdapter
        childRecyclerView.layoutManager = LinearLayoutManager(itemView.context, LinearLayoutManager.HORIZONTAL, false)
    }

    fun bind(category: CategoryWithItems) {
        // 绑定分类名称等父级视图
        itemView.findViewById<TextView>(R.id.tv_category_name).text = category.category.name
        // 仅更新子Adapter的数据,不重建Adapter
        childAdapter.submitList(category.itemQuantityList)
    }
}

步骤4:处理商品数量更新的逻辑

当用户点击子商品卡片更新数量时:

  1. 修改数据源中对应商品的quantity值
  2. 调用父ListAdapter的submitList方法传入更新后的完整数据列表
  3. 父级DiffUtil会判定分类项未变化,不会刷新父item;子Adapter则会通过自身DiffUtil计算出仅数量变化的商品项,只重绘该卡片

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 04:55:58