如何实现嵌套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:处理商品数量更新的逻辑
当用户点击子商品卡片更新数量时:
- 修改数据源中对应商品的
quantity值 - 调用父ListAdapter的
submitList方法传入更新后的完整数据列表 - 父级DiffUtil会判定分类项未变化,不会刷新父item;子Adapter则会通过自身DiffUtil计算出仅数量变化的商品项,只重绘该卡片
内容的提问来源于stack exchange,提问作者perissf
相关产品推荐
相关产品推荐

