DiffUtil Inconsistency detected Invalid view holder adapter position的处理

如果计算的是从上一次更改以来的更改,则根本不会报这个错误,报这个错误是因为计算的差异不是从上一次更改以来的更改

把datas.add(temp)注释就会报这个错误

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_diff_util_test001)
        val btnChange = findViewById<Button>(R.id.btn_change)
        val recyclerView = findViewById<RecyclerView>(R.id.recycler_view)
        val datas = mutableListOf<String>()
        for(i in 1..3){
            datas.add("item $i")
        }
        val adapter = DiffUtilsTest001Adapter(datas, this)
        recyclerView.adapter = adapter
        recyclerView.layoutManager = LinearLayoutManager(this)


        val newDatas = mutableListOf<String>()
        datas.forEach { str ->
            newDatas.add(str)
        }
        var index = 1000
        btnChange.setOnClickListener {
            val temp = "new item ${index++}"
            newDatas.add(temp)
            adapter.datas = newDatas
            //理论上应该计算从上一次更改以来的更改
            //如果计算的不是从上一次更改以来的更改,则将dispatchUpdatesTo()发送到adapter,会有问题
            //比如报Inconsistency detected Invalid view holder adapter position这个错误
            val res = DiffUtil.calculateDiff(MyDiffCallback(datas, newDatas), false)
            res.dispatchUpdatesTo(adapter)

            //也加入到datas,免得下次点击时,datas和newDatas差距过大,刷新的内容过大
            //不加进去还会造成 Inconsistency detected Invalid view holder adapter position这个bug
            //新旧内容的差距过大会造成 Inconsistency detected Invalid view holder adapter position这个bug
            datas.add(temp)
        }
    }

一种处理方法(就算计算的不是从上次更改以来的更改,也不会报错)。思路就是自定义一个LayoutManager,然后把异常吃掉

class WrapContentLinearLayoutManager : LinearLayoutManager {
    constructor(context: Context?) : super(context)
    constructor(context: Context?, orientation: Int, reverseLayout: Boolean) : super(
        context,
        orientation,
        reverseLayout
    )

    constructor(
        context: Context?,
        attrs: AttributeSet?,
        defStyleAttr: Int,
        defStyleRes: Int
    ) : super(context, attrs, defStyleAttr, defStyleRes) {
    }

    override fun onLayoutChildren(recycler: RecyclerView.Recycler, state: RecyclerView.State) {
        try {
            super.onLayoutChildren(recycler, state)
        } catch (e: IndexOutOfBoundsException) {
            Log.e("Error", "IndexOutOfBoundsException in RecyclerView happens")
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值