如何在回收器视图中正确使用DiffUtils来更新数组列表?



我正在实现recyclerview通知列表的困难。而搜索过滤器的回收视图困难的工作。但是当我点击列表项应用程序崩溃与java.lang。IndexOutOfBoundsException: Index: 1, Size: 1在同一时间,当我使用notifyDataSetChanged()应用程序没有崩溃。

模型类

data class LanguageModel (
@SerializedName("languageName")
var languageName : String = "",
@SerializedName("languageNativeName")
var languageNativeName : String = "",
@SerializedName("languageCode")
var languageCode : String = "",
@SerializedName("updatedAt")
var updatedAt : String = "",
@SerializedName("defaultLanguage")
var defaultLanguage : Boolean = false
)

适配器类
class LanguageSelectionAdapter(var languageModelList : ArrayList<LanguageModel>, var itemClick : LanguageClick)
: RecyclerView.Adapter<LanguageSelectionAdapter.LanguageSelectionVH>() {
inner class LanguageSelectionVH(val binding: LanguageListSingleItemBinding)
: RecyclerView.ViewHolder(binding.root)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): LanguageSelectionVH {
val binding = LanguageListSingleItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return LanguageSelectionVH(binding)
}
override fun onBindViewHolder(holder: LanguageSelectionVH, position: Int) {
val model = languageModelList[position]
holder.binding.languageCard.apply {
if (position == 0 && position % 2 == 0) {
setCardBackgroundColor(ContextCompat.getColor(context, R.color.main_blue))
} else {
setCardBackgroundColor(ContextCompat.getColor(context, R.color.main_green))
}
}
holder.binding.nativeLanguageText.text = model.languageNativeName
holder.binding.originalLanguageText.text = model.languageName
holder.itemView.setOnClickListener {
itemClick.langClick(position)
}
}
override fun getItemCount(): Int {
return languageModelList.size
}
fun setData(newLanguageModelList : ArrayList<LanguageModel>) {
val diffCallback = LanguageSelectionDiffUtils(languageModelList, newLanguageModelList)
val diffResult = DiffUtil.calculateDiff(diffCallback)
languageModelList.clear()
languageModelList.addAll(newLanguageModelList)
diffResult.dispatchUpdatesTo(this)
}
}

Diffutil类

class LanguageSelectionDiffUtils(
private val oldList : ArrayList<LanguageModel>,
private val newList : ArrayList<LanguageModel>
) : DiffUtil.Callback(){
override fun getOldListSize(): Int {
return oldList.size
}
override fun getNewListSize(): Int {
return newList.size
}
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
return oldList[oldItemPosition].updatedAt == newList[newItemPosition].updatedAt
}
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
val (languageName, languageNativeName, languageCode, updatedAt,defaultLanguage) = oldList[oldItemPosition]
val (languageName1, languageNativeName1, languageCode1, updatedAt1,defaultLanguage1) = newList[newItemPosition]
return languageName == languageName1
&& languageNativeName == languageNativeName1
&& languageCode == languageCode1
&& updatedAt == updatedAt1
&& defaultLanguage == defaultLanguage1
}

@Nullable
override fun getChangePayload(oldItemPosition: Int, newItemPosition: Int): Any? {
return super.getChangePayload(oldItemPosition, newItemPosition)
}
}

我需要使用困难更新recyclerview请告知我的代码是否有任何修改

Thanks in advance

您可以查看此回购Githup ripo

我试着编辑你的代码

<script src="https://gist.github.com/alihrhera/109ec71245e40c953451a68627a1dc60.js"></script>

运行时GIF代码

过滤器查询

private fun perFormFilter(filterText : String) {
languageList = ArrayList()
if (filterText.isEmpty() || filterText == null) {
languageList = languageMainList
} else {
for (i in 0 until languageMainList.size) {
if (languageMainList[i].languageName.lowercase(Locale.ROOT).contains(filterText.lowercase(Locale.ROOT)) ||
languageMainList[i].languageNativeName.lowercase(Locale.ROOT).contains(filterText.lowercase(Locale.ROOT)) ||
languageMainList[i].languageCode.lowercase(Locale.ROOT).contains(filterText.lowercase(Locale.ROOT))
) {
languageList.add(languageMainList[i])
}
}
}
languageSelectionAdapter.setData(languageList)
//languageSelectionAdapter.notifyDataSetChanged()
}

最新更新