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

同ViewType但视图边界不同的RecyclerView共享RecycledViewPool异常排查

问题原因与解决方案

核心问题

RecycledViewPool是按ViewType区分缓存ViewHolder的,你两个RecyclerView的ViewType相同,所以池子里的ViewHolder会被互相复用。但你只在onCreateViewHolder里设置宽度——这个方法只有创建新ViewHolder时才会执行,复用ViewHolder时不会走这个逻辑,旧的宽度就被保留下来,导致同一列表里出现两种宽度的Item。

两种解决办法

1. 给两个RecyclerView设置不同的ViewType

既然两个Item的布局尺寸本质不同,就应该把它们归为不同的视图类型,让RecycledViewPool分开缓存:

RecyclerView1的Adapter修改:

override fun getItemViewType(position: Int): Int {
    return 1 // 自定义唯一的ViewType值
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder<HomeData> {
    val viewHolder = super.onCreateViewHolder(parent, viewType)
    val view = viewHolder.itemView
    view.setWidth(100)
    return viewHolder
}

RecyclerView2的Adapter修改:

override fun getItemViewType(position: Int): Int {
    return 2 // 和RecyclerView1的ViewType区分开
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder<HomeData> {
    val viewHolder = super.onCreateViewHolder(parent, viewType)
    val view = viewHolder.itemView
    view.setWidth(80)
    return viewHolder
}

2. 在onBindViewHolder中重置Item宽度

如果不想修改ViewType,就在每次绑定数据时强制设置宽度——不管ViewHolder是新创建还是复用的,都会执行onBindViewHolder,能保证显示时宽度正确:

RecyclerView1的Adapter修改:

override fun onBindViewHolder(holder: BaseViewHolder<HomeData>, position: Int) {
    super.onBindViewHolder(holder, position)
    holder.itemView.setWidth(100) // 绑定数据时重置宽度
    // 你的其他数据绑定逻辑
}

RecyclerView2的Adapter修改:

override fun onBindViewHolder(holder: BaseViewHolder<HomeData>, position: Int) {
    super.onBindViewHolder(holder, position)
    holder.itemView.setWidth(80) // 绑定数据时重置宽度
    // 你的其他数据绑定逻辑
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 06:24:18