Android RecyclerView行数据相近但条目尺寸不一致异常排查
问题根因
列表条目尺寸不一致的核心原因出在Adapter的Item布局加载逻辑上,同时代码里存在两个会引发崩溃和逻辑错误的隐患:
- 核心错误:
onCreateViewHolder中使用ViewBinding加载Item布局时,没有传入父容器parent参数,也未正确指定attachToRoot属性。这种写法会导致Item布局无法继承RecyclerView的布局测量规则,XML中定义的layout_height="40dp"、layout_width="match_parent"等布局参数失效,View复用时测量逻辑紊乱,最终出现同数据下条目尺寸不一致的现象。 - 隐患1:Fragment中使用
listOf()生成只读列表后强转为MutableList,后续执行删除操作时会触发UnsupportedOperationException崩溃。 - 隐患2:删除条目后仅调用
notifyItemRemoved()未刷新后续条目位置,会导致后续删除按钮点击时position错位,删错条目。
修复方案
1. 修正Adapter的Item布局加载逻辑
修改AddedItemsAdapter的onCreateViewHolder方法,传入正确的inflate参数:
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AddedItemsViewHolder { // 传入parent作为布局参数依赖,attachToRoot设为false由RecyclerView管理Item挂载 return AddedItemsViewHolder( ListitemAddedItemsBinding.inflate( LayoutInflater.from(parent.context), parent, false ) ) }
注:这里直接使用parent.context获取布局加载器的上下文,比外部传入context更稳妥,可避免上下文不一致引发的主题、资源加载错误。
2. 修复列表初始化的类型强转问题
修改Fragment中items的初始化代码,直接使用可变列表构造方法,避免强转导致的删除崩溃:
items = mutableListOf( AddedItem("Alma", Metric("Ton", 3)), AddedItem("Armud", Metric("Sentner", 11)), AddedItem("Heyva", Metric("Sentner", 1)), AddedItem("Nar", Metric("KG", 980)), AddedItem("Pomidor", Metric("Ton", 2)), AddedItem("Pomidor", Metric("Ton", 2)), AddedItem("Pomidor", Metric("Ton", 2)), AddedItem("Kartof", Metric("Ton", 1)), AddedItem("Kartof", Metric("Ton", 1)), AddedItem("Pomidor", Metric("Ton", 1)), AddedItem("Pomidor", Metric("Ton", 1)), AddedItem("Kartof", Metric("Ton", 1)), AddedItem("Kartof", Metric("Ton", 1)) )
3. 修复删除后的position错位问题
修改Adapter的itemRemoved方法,删除条目后刷新后续条目的位置:
fun itemRemoved(newItems: MutableList<AddedItem>, position: Int){ items = newItems notifyItemRemoved(position) // 刷新position之后所有条目的位置,避免点击事件拿到错误position notifyItemRangeChanged(position, items.size - position) }
完成以上修改后,列表条目会严格按照XML定义的40dp高度渲染,不会再出现尺寸不一致的问题,同时修复了隐藏的崩溃和逻辑错位bug。
内容的提问来源于stack exchange,提问作者Huseynbaba
相关产品推荐
相关产品推荐

