Android java.lang.IndexOutOfBoundsException:检测到不一致。使用DiffUtil时,视图保持器适配器无效

Android java.lang.IndexOutOfBoundsException:检测到不一致。使用DiffUtil时,视图保持器适配器无效,android,kotlin,android-recyclerview,adapter,android-diffutils,Android,Kotlin,Android Recyclerview,Adapter,Android Diffutils,下面是一个适配器类,用于在recycler视图中加载所有书籍项目。使用了DiffUtils,因此不会通知整个列表 class BooksAdapter(var mContext: Context) : RecyclerView.Adapter<BooksAdapter.BooksViewHolder>() { var books: List<BookTable> = ArrayList() set(value) { va

下面是一个适配器类,用于在recycler视图中加载所有书籍项目。使用了DiffUtils,因此不会通知整个列表


class BooksAdapter(var mContext: Context) : RecyclerView.Adapter<BooksAdapter.BooksViewHolder>() {

    var books: List<BookTable> = ArrayList()
        set(value) {
            val result = DiffUtil.calculateDiff(BookListDiffCallBacks(ArrayList(value), ArrayList(books)))
            field = value
            result.dispatchUpdatesTo(this)
        }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BooksViewHolder {
        val binding = DataBindingUtil.inflate<ItemBookBinding>(LayoutInflater.from(mContext), R.layout.item_book, parent, false)
        return BooksViewHolder(binding)
    }

    override fun getItemCount(): Int {
        return books.size
    }

    override fun onBindViewHolder(holder: BooksViewHolder, position: Int) {
        holder.setData(books[position])
    }

    inner class BooksViewHolder(var binding: ItemBookBinding) : RecyclerView.ViewHolder(binding.root) {
        fun setData(bookTable: BookTable) {
            binding.book = bookTable
        }
    }
}

我的应用程序崩溃,我遇到以下错误:

java.lang.IndexOutOfBoundsException:检测到不一致。视图保持架适配器位置无效

我已经实现了DiffUtil类,这样就不会通知整个recycleview视图项


class BooksAdapter(var mContext: Context) : RecyclerView.Adapter<BooksAdapter.BooksViewHolder>() {

    var books: List<BookTable> = ArrayList()
        set(value) {
            val result = DiffUtil.calculateDiff(BookListDiffCallBacks(ArrayList(value), ArrayList(books)))
            field = value
            result.dispatchUpdatesTo(this)
        }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BooksViewHolder {
        val binding = DataBindingUtil.inflate<ItemBookBinding>(LayoutInflater.from(mContext), R.layout.item_book, parent, false)
        return BooksViewHolder(binding)
    }

    override fun getItemCount(): Int {
        return books.size
    }

    override fun onBindViewHolder(holder: BooksViewHolder, position: Int) {
        holder.setData(books[position])
    }

    inner class BooksViewHolder(var binding: ItemBookBinding) : RecyclerView.ViewHolder(binding.root) {
        fun setData(bookTable: BookTable) {
            binding.book = bookTable
        }
    }
}


参考:

您对
BookListDiffCallBacks
构造函数的参数是向后的:

val result = DiffUtil.calculateDiff(BookListDiffCallBacks(ArrayList(value), ArrayList(books)))

您正在传递
new,old
,但构造函数希望
old,new
您向
BookListDiffCallBacks
构造函数传递的参数是向后的:

val result = DiffUtil.calculateDiff(BookListDiffCallBacks(ArrayList(value), ArrayList(books)))

您正在传递
new,old
,但构造函数希望
old,new

,如果我找到了解决方法,则该错误有时可能仍然存在。谢谢,@Ryan,你付出了宝贵的努力。其实你的解决方案解决了我的问题,下面给出的就是预防

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: Recycler, state: RecyclerView.State) {
        try {
            super.onLayoutChildren(recycler, state)
        } catch (e: IndexOutOfBoundsException) {
            Log.e("Error", "IndexOutOfBoundsException in RecyclerView happens")
        }
    }
}

有时,如果我找到了解决方法,那么这个错误仍然会存在。谢谢,@Ryan,你付出了宝贵的努力。其实你的解决方案解决了我的问题,下面给出的就是预防

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: Recycler, state: RecyclerView.State) {
        try {
            super.onLayoutChildren(recycler, state)
        } catch (e: IndexOutOfBoundsException) {
            Log.e("Error", "IndexOutOfBoundsException in RecyclerView happens")
        }
    }
}