gil*_*emy 2 android android-recyclerview android-diffutils android-listadapter
我使用 a 的绑定ListAdapter和 a 的定义DiffUtil.ItemCallback。删除项目(至少 2 个)时,我有一个IndexOutOfBoundsException. 列表的更新有效(删除后元素的数量确实是N-1),但项目的位置不起作用,保留的是调用。因此,在调用时会抛出异常getItem(position)(在 中onBindViewHolder)。getItemCount()注意:之前的日志getItem(position)显示列表包含 N-1 个元素。我创建了一个小型存储库:https://github.com/jeremy-giles/DiffListAdapterTest(与我的项目具有相同的配置),它重现了问题。
项目适配器类
class ItemAdapter(
var listener: ListAdapterListener) : DataBindingAdapter<Item>(DiffCallback()) {
class DiffCallback : DiffUtil.ItemCallback<Item>() {
override fun areItemsTheSame(oldItem: Item, newItem: Item): Boolean {
return oldItem == newItem
}
override fun areContentsTheSame(oldItem: Item, newItem: Item): Boolean {
return oldItem == newItem
}
}
override fun getItemViewType(position: Int) = R.layout.recycler_item
override fun onBindViewHolder(holder: DataBindingViewHolder<Item>, position: Int) {
super.onBindViewHolder(holder, position)
holder.itemView.tv_position.text = "Pos: $position"
holder.itemView.setOnLongClickListener {
Timber.d("List item count: ${itemCount}, position: $position")
listener.onLongViewClick(getItem(position), position)
}
}
interface ListAdapterListener {
fun onLongViewClick(item: Item, position: Int) : Boolean
}
}
Run Code Online (Sandbox Code Playgroud)
BindingUtils 类
abstract class DataBindingAdapter<T>(diffCallback: DiffUtil.ItemCallback<T>) :
ListAdapter<T, DataBindingViewHolder<T>>(diffCallback) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DataBindingViewHolder<T> {
val layoutInflater = LayoutInflater.from(parent.context)
val binding = DataBindingUtil.inflate<ViewDataBinding>(layoutInflater, viewType, parent, false)
return DataBindingViewHolder(binding)
}
override fun onBindViewHolder(holder: DataBindingViewHolder<T>, position: Int) {
holder.bind(getItem(position))
}
}
class DataBindingViewHolder<T>(private val binding: ViewDataBinding) :
RecyclerView.ViewHolder(binding.root) {
fun bind(item: T) {
binding.setVariable(BR.item, item)
binding.executePendingBindings()
}
}
Run Code Online (Sandbox Code Playgroud)
在我的MainActivity类中,我使用 aLiveData来更新recyclerView
itemViewModel.getListObserver().observe(this, Observer {
Timber.d("List Observer, items count ${it.size}")
itemAdapter.submitList(it.toList())
})
Run Code Online (Sandbox Code Playgroud)
在 onBindViewHolder 中将“position”的使用更新为“holder.getAdapterPosition()”:
override fun onBindViewHolder(holder: DataBindingViewHolder<Item>, position: Int) {
super.onBindViewHolder(holder, position)
holder.itemView.tv_position.text = "Pos: $position"
holder.itemView.setOnLongClickListener {
Timber.d("List item count: ${itemCount}, position: $position")
listener.onLongViewClick(getItem(holder.getAdapterPosition()), holder.getAdapterPosition())
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2996 次 |
| 最近记录: |