下面是一个适配器类,用于在回收器视图中加载所有图书项目。使用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
}
}
}
class BookListDiffCallBacks(var oldBooks: ArrayList<BookTable>, var newBooks: ArrayList<BookTable>) : DiffUtil.Callback() {
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
return oldBooks[oldItemPosition].bookId == newBooks[newItemPosition].bookId
}
override fun getOldListSize(): Int {
return oldBooks.size
}
override fun getNewListSize(): Int {
return newBooks.size
}
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
return oldBooks[oldItemPosition] == newBooks[newItemPosition]// == means structural equality checks in kotlin
}
override fun getChangePayload(oldItemPosition: Int, newItemPosition: Int): Any? {
return super.getChangePayload(oldItemPosition, newItemPosition)
}
}
@Entity(
tableName = "book_table"//,
// foreignKeys = [ForeignKey(entity = CategoryTable::class, parentColumns = arrayOf("categoryId"), childColumns = arrayOf("categoryId"), onDelete = ForeignKey.CASCADE)]
)
class BookTable : BaseObservable() {
@Bindable
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "bookId")
var bookId: Int = 0
set(value) {
field = value
notifyPropertyChanged(BR.bookId)
}
@Bindable
var name: String? = null
set(value) {
field = value
notifyPropertyChanged(BR.name)
}
@Bindable
var categoryId: Int? = null
set(value) {
field = value
notifyPropertyChanged(BR.categoryId)
}
override fun equals(other: Any?): Boolean {
if (other === this) return true // means same reference
if (other !is BookTable) return false// is not of same class
// other is now Booktable instance as above condition false if you remove that condition then it will show error in below condition
// as it has passed above condition means it is of type BookTable
return (bookId == other.bookId
&& categoryId == other.categoryId
&& name == other.name)
}
override fun hashCode(): Int {
var result = bookId
result = 31 * result + (name?.hashCode() ?: 0)
result = 31 * result + (categoryId ?: 0)
return result
}
}
我已经实现了DiffUtil类,这样就不会通知整个Recyview视图项。
参考:https://developer.android.com/reference/kotlin/androidx/recycerview/widget/diffutil
BookListDiffCallbacks
构造函数的参数是向后的:
val result = DiffUtil.calculateDiff(BookListDiffCallBacks(ArrayList(value), ArrayList(books)))
您传递的是new,old
,但是构造函数需要old,new
。
我有一个RxJava2可观察到,它接受两个列表,为它们计算diff结果,并将此数据发送到适配器。适配器在主线程上调度更新。 我检测到不一致。在某些设备上有时出现无效视图保持器适配器PositionViewHolder错误。我也搞不清我的代码出了什么问题。最小SDK 21,目标SDK 26,RecyclerView版本为26.0.0。我知道扩展LinearLayoutManager和静默捕获此错误的
同时,我编写了一个自定义适配器,可以添加页眉和页脚。我使用了这个适配器,并添加了一个加载更多页脚,这样我的列表在向下滚动时可以加载更多。这导致了一点:我的列表,可以加载更多,将始终包含至少一个项目(加载更多页脚)。 为避免误解,下面的“项目”一词将特别表示项目不是页眉或页脚。 然后,当我通过diffUtil将项目从n(n>0)项通知为零时,问题发生了,我的应用程序崩溃。 值得一提的是,如果我使用没
致命异常:检测到java.lang.IndexOutOfBoundsException不一致。无效的物料位置5(偏移量:5)。状态:24 这种撞车的情况太多了!!! 我在布料上弄到的。 DateList是涉及RecyclerView片段: callToServer(带有假输入)首先清除键列表,然后填充它。几毫秒后,将调用callToServer(具有true输入)来再次清除keyList,并填充新
我有一个“回收者”视图,它在除三星以外的所有设备上都能完美运行。在三星上,我明白了 JAVAlang.IndexOutOfBoundsException:检测到不一致。视图保持架适配器位置无效视图保持架 当我从另一个活动的“回收者”视图返回片段时。 适配器代码: 例外: 我该怎么解决这个问题?
我已经开始在Crashlytics上报道这次坠机事件。我不知道如何复制它,但它似乎都是内部的代码。我认为这来自于我的<代码>回收视图</代码>它从未真正改变过。用户可以刷新它,但随后会替换所有项,并调用。
我的应用程序中有回收器视图。UI类似于Google Play Store应用程序。它有两个视图寻呼机和项目的列表和网格以交替的方式。所有数据都是从web服务中提取的,并在两个API调用中被分叉。列表和网格的数据是从另一个API填充的。问题是,当我快速滚动recyclerview时,我会遇到这种崩溃。滚动recyclerview时,用于在列表/网格中加载数据的API调用来自。阅读了许多关于这个主题的
我们的QA检测到了一个bug:当旋转Android设备(Droid Turbo)时,发生了以下与RecyclerView相关的崩溃: java.lang.IndexOutOfBoundsException:检测到不一致。无效的物料位置%2(偏移量:%2)。状态:%3 对我来说,这看起来像是RecyclerView内部的一个内部错误,因为我想不出这是由我们的代码直接导致的任何方式... 有人遇到过这