Kotlin ListAdapter复位RecyclerView后提交列表



我正在使用MVVM和数据绑定开发android应用程序。我使用ListAdapter为我的RecyclerView适配器。这种情况是,当我使用submitList向适配器提交新数据时,它会重置RecyclerView滚动位置。它一开始会闪烁,然后重置位置到顶部。

My Binding Adapter

@BindingAdapter("listTemplate", "hirarki")
fun bindListTemplate(recyclerView: RecyclerView, data: List<Template>?, hirarki: Int) {
var adapter = recyclerView.adapter as TemplateChiefAdapter
adapter.submitList(data)

}

TemplateFragment重新提交数据

navController.currentBackStackEntry?.savedStateHandle?.getLiveData<Boolean>("shouldUpdate")
?.observe(viewLifecycleOwner, {
if (it) {
viewModel.fetchdata()
navController.currentBackStackEntry?.savedStateHandle?.remove<Boolean>("shouldUpdate")
}
})

这段代码将更新我的ViewModel中的LiveData,因此DataBinding将检测到它的更改并将数据重新提交给适配器

My List Adapter

class TemplateChiefAdapter(val onClickListener: OnClickListener) : ListAdapter<Template, TemplateChiefAdapter.TemplateChiefViewHolder>(DiffCallback) {
class TemplateChiefViewHolder(private var binding: ItemTemplateChiefBinding) : RecyclerView.ViewHolder(binding.root) {
fun bind(template: Template) {
binding.template = template
binding.executePendingBindings()
}
}
companion object DiffCallback : DiffUtil.ItemCallback<Template>() {
override fun areItemsTheSame(oldItem: Template, newItem: Template): Boolean {
return oldItem === newItem
}
override fun areContentsTheSame(oldItem: Template, newItem: Template): Boolean {
return oldItem.id_template == newItem.id_template
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TemplateChiefViewHolder {
return TemplateChiefViewHolder(ItemTemplateChiefBinding.inflate(LayoutInflater.from(parent.context)))
}
override fun onBindViewHolder(holder: TemplateChiefViewHolder, position: Int) {
val template = getItem(position)
holder.itemView.setOnClickListener {
onClickListener.onClick(template)
}
holder.bind(template)
}
class OnClickListener(val listener: (template: Template) -> Unit) {
fun onClick(template: Template) = listener(template)
}
}

如何在调用submitList后保持回收器滚动位置?

我没有详细检查所有你的代码,但是DiffUtil回调引起了我的注意。

areItemsTheSame是来自DiffUtil类的优化,用于确定项目是否改变了位置。如果没有,则可以检查内容,并在更改时将其重新绑定到新数据。如果位置改变了,那么项目可能需要在其他地方动画。你可以想象,从那时起事情变得更加复杂了。

该方法的思想是比较项是否相同,而不是比较整个项。我会使用id(或任何可以帮助您识别物品唯一性的东西)。您正在使用===操作符,我不知道您的架构的其余部分,但是通过引用进行比较可能不准确,例如,如果您的数据层转换和复制这些对象(在适配器中您不能/不应该告诉/关心的事情)。

例如,而不是

return oldItem === newItem

你可以做

return oldItem.someId === newItem.someId
这将确保即使你的项目是相同的,但被复制/重新创建等。,尽管它们是不同的引用,你仍然会这样识别它们。

然后,在areContentsTheSame中,您应该检查所有您认为有助于决定onBind是否必须在您的特定viewHolder上调用的内容,因为内容不同。所以我希望是这样的:

oldItem.something == newItem.something
&& oldItem.xxx == newItem.xxx
&& oldItem.yyy == newItem.yyy

(但也许与数据绑定你不需要这个,我不知道)。

话虽如此,我对数据绑定有0.1的经验(对我个人来说这已经足够了),所以如果这与数据绑定库的行为有关,我不能再帮助你了。:/

从一个RecyclerView的角度来看,剩下的代码看起来足够

相关内容

  • 没有找到相关文章

最新更新