List Adapter Diff Util 不更新 Recyclerview 中的列表项
List Adapter Diff Util not updating the List Item in Recyclerview
List Adapter diffutil 未更新 recyclerview 中的列表项。
当我从列表中添加或删除项目时,它会起作用。但不更新对象 class
中的任何特定值,例如 isSelected : Boolean = false
当列表中的一个对象 class 发生变化时如何更新 recyclerview 视图,例如一个对象中的布尔值变化 class
谢谢
适配器Class低于
class CategoryMainAdapter(
var itemClick : CategoryItemClick,
var screenWidth : Int = 0
) : ListAdapter<CategoryModel, CategoryMainAdapter.CategoryMainViewHolder>(CategoryMainDiffUtils()) {
inner class CategoryMainViewHolder(val binding : CategorySingleListLayoutBinding) : RecyclerView.ViewHolder(binding.root)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CategoryMainViewHolder {
val binding = CategorySingleListLayoutBinding.inflate(LayoutInflater.from
(parent.context),
parent,
false
)
return CategoryMainViewHolder(binding)
}
override fun onBindViewHolder(holder: CategoryMainViewHolder, position: Int) {
val model = getItem(position)
holder.apply {
binding.apply {
mainLinearLayout.layoutParams.apply {
width = ((screenWidth*22.5).toInt())/100
height = (((screenWidth*22.5)/100)*1.2).toInt()
}
categoryName.text = model.name
backgroundColor.setBackgroundColor(model.colorCode)
categoryImage.load(getImageCorrectImage(model.image, model.secondaryImage)) {
error(R.drawable.ic_food_place_holder)
}
if (model.isSelected) {
categoryName.setTextColor(ContextCompat.getColor(categoryName.context, R.color.main_blue))
selectedView.setBackgroundResource(R.drawable.main_blue_curved_bg)
categoryImage.apply {
animation = AnimationUtils.loadAnimation(context, R.anim.category_zoom_in_anim)
setPadding(0, 0, 0, 0)
}
} else {
categoryName.setTextColor(setColorByAttrProgrammatically(categoryName.context, R.attr.colorOnSecondary))
selectedView.setBackgroundResource(android.R.color.transparent)
categoryImage.apply {
animation = AnimationUtils.loadAnimation(context, R.anim.category_zoom_out_anim)
setPadding(1, 1, 1, 1)
}
}
}
itemView.apply {
setOnClickListener {
itemClick.onCategoryClick(model)
}
}
}
}
class CategoryMainDiffUtils : DiffUtil.ItemCallback<CategoryModel>() {
override fun areItemsTheSame(oldItem: CategoryModel, newItem: CategoryModel): Boolean {
return oldItem.isSelected == newItem.isSelected
}
override fun areContentsTheSame(oldItem: CategoryModel, newItem: CategoryModel): Boolean {
return oldItem == newItem
}
}
override fun submitList(list: MutableList<CategoryModel>?) {
super.submitList(list?.let { ArrayList(it) })
}
}
更改后属性您必须更新适配器数据列表并调用。
adapter.notifyDataSetChanged()
尝试将您的 DiffUtil 更新为:
class CategoryMainDiffUtils : DiffUtil.ItemCallback<CategoryModel>() {
override fun areItemsTheSame(oldItem: CategoryModel, newItem: CategoryModel): Boolean {
return oldItem.id == newItem.id // or compare something unique
}
override fun areContentsTheSame(oldItem: CategoryModel, newItem: CategoryModel): Boolean {
return oldItem == newItem // or if data class is large, compare only things that might change, also please note that only data class on kotlin has auto generated equals() method
}
}
首先,areContentsTheSame
和 areItemsTheSame
的实现可能需要切换。 areContentsTheSame
是检查您的物品中的东西是否不同的那个。 areItemsTheSame
是关于是否是同一项。如果项目有一个 id,你可能想要比较它们而不是项目本身。但仅此一项可能无法解决您的问题。
事实是,如果列表包含不可变的项目,ListAdapter 的效果最好。理想情况下,您希望每次调用 submitList
时都提交一个新列表。因为如果你在现有的 lisk 中更改 属性 就像 isSelected
并简单地使用相同的列表调用 submitList 什么都不会发生。
所以您要做的不是更改 isSelected
属性,而是需要创建列表的副本,仅在该副本中更改 isSelected
并通过复制到 submitList
.
制作起来可能很乏味。另一种可能有效的丑陋解决方法是添加第二个 属性 可能称为 oldIsSelected
并且只在 DiffUtil 本身中更改那个,像这样
override fun areContentsTheSame(oldItem: CategoryModel, newItem: CategoryModel): Boolean {
val result = oldItem.oldIsSelected == newItem.isSelected
newItem.oldIsSelected = newItem.isSelected
return result
}
List Adapter diffutil 未更新 recyclerview 中的列表项。
当我从列表中添加或删除项目时,它会起作用。但不更新对象 class
中的任何特定值,例如isSelected : Boolean = false
当列表中的一个对象 class 发生变化时如何更新 recyclerview 视图,例如一个对象中的布尔值变化 class
谢谢
适配器Class低于
class CategoryMainAdapter(
var itemClick : CategoryItemClick,
var screenWidth : Int = 0
) : ListAdapter<CategoryModel, CategoryMainAdapter.CategoryMainViewHolder>(CategoryMainDiffUtils()) {
inner class CategoryMainViewHolder(val binding : CategorySingleListLayoutBinding) : RecyclerView.ViewHolder(binding.root)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CategoryMainViewHolder {
val binding = CategorySingleListLayoutBinding.inflate(LayoutInflater.from
(parent.context),
parent,
false
)
return CategoryMainViewHolder(binding)
}
override fun onBindViewHolder(holder: CategoryMainViewHolder, position: Int) {
val model = getItem(position)
holder.apply {
binding.apply {
mainLinearLayout.layoutParams.apply {
width = ((screenWidth*22.5).toInt())/100
height = (((screenWidth*22.5)/100)*1.2).toInt()
}
categoryName.text = model.name
backgroundColor.setBackgroundColor(model.colorCode)
categoryImage.load(getImageCorrectImage(model.image, model.secondaryImage)) {
error(R.drawable.ic_food_place_holder)
}
if (model.isSelected) {
categoryName.setTextColor(ContextCompat.getColor(categoryName.context, R.color.main_blue))
selectedView.setBackgroundResource(R.drawable.main_blue_curved_bg)
categoryImage.apply {
animation = AnimationUtils.loadAnimation(context, R.anim.category_zoom_in_anim)
setPadding(0, 0, 0, 0)
}
} else {
categoryName.setTextColor(setColorByAttrProgrammatically(categoryName.context, R.attr.colorOnSecondary))
selectedView.setBackgroundResource(android.R.color.transparent)
categoryImage.apply {
animation = AnimationUtils.loadAnimation(context, R.anim.category_zoom_out_anim)
setPadding(1, 1, 1, 1)
}
}
}
itemView.apply {
setOnClickListener {
itemClick.onCategoryClick(model)
}
}
}
}
class CategoryMainDiffUtils : DiffUtil.ItemCallback<CategoryModel>() {
override fun areItemsTheSame(oldItem: CategoryModel, newItem: CategoryModel): Boolean {
return oldItem.isSelected == newItem.isSelected
}
override fun areContentsTheSame(oldItem: CategoryModel, newItem: CategoryModel): Boolean {
return oldItem == newItem
}
}
override fun submitList(list: MutableList<CategoryModel>?) {
super.submitList(list?.let { ArrayList(it) })
}
}
更改后属性您必须更新适配器数据列表并调用。
adapter.notifyDataSetChanged()
尝试将您的 DiffUtil 更新为:
class CategoryMainDiffUtils : DiffUtil.ItemCallback<CategoryModel>() {
override fun areItemsTheSame(oldItem: CategoryModel, newItem: CategoryModel): Boolean {
return oldItem.id == newItem.id // or compare something unique
}
override fun areContentsTheSame(oldItem: CategoryModel, newItem: CategoryModel): Boolean {
return oldItem == newItem // or if data class is large, compare only things that might change, also please note that only data class on kotlin has auto generated equals() method
}
}
首先,areContentsTheSame
和 areItemsTheSame
的实现可能需要切换。 areContentsTheSame
是检查您的物品中的东西是否不同的那个。 areItemsTheSame
是关于是否是同一项。如果项目有一个 id,你可能想要比较它们而不是项目本身。但仅此一项可能无法解决您的问题。
事实是,如果列表包含不可变的项目,ListAdapter 的效果最好。理想情况下,您希望每次调用 submitList
时都提交一个新列表。因为如果你在现有的 lisk 中更改 属性 就像 isSelected
并简单地使用相同的列表调用 submitList 什么都不会发生。
所以您要做的不是更改 isSelected
属性,而是需要创建列表的副本,仅在该副本中更改 isSelected
并通过复制到 submitList
.
制作起来可能很乏味。另一种可能有效的丑陋解决方法是添加第二个 属性 可能称为 oldIsSelected
并且只在 DiffUtil 本身中更改那个,像这样
override fun areContentsTheSame(oldItem: CategoryModel, newItem: CategoryModel): Boolean {
val result = oldItem.oldIsSelected == newItem.isSelected
newItem.oldIsSelected = newItem.isSelected
return result
}