android #kotlin #arraylist #android-recyclerview #android-diffutils
#Android #kotlin #arraylist #android-recyclerview #android-diffutils
Вопрос:
Я внедряю diffutils для recyclerview для уведомления списка. Во время фильтрации поиска 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 amp;amp; 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
amp;amp; languageNativeName == languageNativeName1
amp;amp; languageCode == languageCode1
amp;amp; updatedAt == updatedAt1
amp;amp; defaultLanguage == defaultLanguage1
}
@Nullable
override fun getChangePayload(oldItemPosition: Int, newItemPosition: Int): Any? {
return super.getChangePayload(oldItemPosition, newItemPosition)
}
}
Мне нужно обновить recyclerview с помощью diffutils
пожалуйста, укажите, есть ли какие-либо исправления в моем коде
Заранее спасибо
Ответ №1:
вы можете проверить это репозиторий Githup ripo
я пытаюсь отредактировать ваш код
<script src="https://gist.github.com/alihrhera/109ec71245e40c953451a68627a1dc60.js"></script>
Комментарии:
1. Спасибо за комментарий. Я делаю то же самое. Все работает нормально, но recyclerview не обновляется, это была моя проблема
2. нет обновления при выполнении whta? добавить, удалить или отредактировать элемент?
3. во время фильтрации поиска
4. где код фильтра?
5. Я добавляю свой запрос фильтра, пожалуйста, проверьте
Ответ №2:
Запрос фильтра
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()
}