DiffUtil回调导致索引超出范围异常 [英] DiffUtil Callback resulting in index out of bounds exception

查看:280
本文介绍了DiffUtil回调导致索引超出范围异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在开发一个具有4个字段的项目列表,可以使用自动完成功能对其进行编辑.基础数据结构是4个字段对及其自动完成建议的列表.在用户编辑之前,一旦用户编辑了一个请求,该建议就为空,而我使用diffutil来检测&将更改分派到适配器.我正在使用redux/mvi模式,因此我在视图模型中计算了diffutil回调,然后将一对传递给我的活动以仅调度更改. 一些代码和错误代码片段的时间:)

I am currently developing a list of items that has 4 fields that can be edited with an autocomplete feature. The underlying data structure is a list of pairs of the 4 fields and their autocomplete suggestions. Before the user edits the suggestions are empty once the user edits a request is fired and i use a diffutil to detect & dispatch the changes to the adapter. I am using the redux/mvi pattern, so i calculate the diffutil call back in the view model then pass a pair to my activity to just dispatch the changes. Time for some code and error snippets :)

错误:

java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter positionViewHolder{88b1b52 position=5 id=-1, oldPos=0, pLpos:0 scrap [attachedScrap] tmpDetached no parent} android.support.v7.widget.RecyclerView{c60ba82 VFED..... ......I. 11,11-1069,990 #7f0900ba app:id/rv_suggestions}, adapter:com.accenture.shiny.screens.classify.ClassifyActivity$setupRecyclerView$1@8f3593, layout:android.support.v7.widget.LinearLayoutManager@1fec9d0, context:com.accenture.shiny.screens.classify.ClassifyActivity@9caa09a

DiffUtil:

class ClassificationDiffCallback(private val oldList: Pair<MutableList<ItemInfo>, AutoCompleteResponse>,
                             private val newList: Pair<MutableList<ItemInfo>, AutoCompleteResponse>) : DiffUtil.Callback() {

override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int) =
        oldList.first!![oldItemPosition].getData<Classification>().id == newList.first!![newItemPosition].getData<Classification>().id


override fun getOldListSize() = oldList.first?.size!!


override fun getNewListSize() = newList.first?.size!!


override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int) =
        newList.first!![newItemPosition].getData<Pair<Classification, AutoCompleteResponse>>() == oldList.first!![oldItemPosition].getData<Pair<Classification, AutoCompleteResponse>>()


override fun getChangePayload(oldItemPosition: Int, newItemPosition: Int): Any? {
    return newList.first!![newItemPosition].getData<Pair<Classification, AutoCompleteResponse>>().second
}
}

ViewModel状态减少:

ViewModel state reduction:

 val currentEditableState = (currentState as EditableClassifyState)
                    val list = currentEditableState.classificationsItemInfoDiffResultPair.first
                    EditableClassifyState(calculateClassificationsDiffResultPair(
                            Observable.fromIterable(list ?: mutableListOf())
                                    .map { itemInfo ->
                                        val classification = when (itemInfo.getData<Any>()) {
                                            is Pair<*, *> -> itemInfo.getData<Pair<Any, DiffUtil.DiffResult>>().first
                                            else -> Unit
                                        }
                                        ItemInfo(Pair(classification, result),
                                                if (classification === Unit) R.layout.manual_classification else R.layout.classification_item_layout)
                                                .setId((classification as? Classification)?.id
                                                        ?: 0)
                                    }.toList().blockingGet(), result))


fun calculateClassificationsDiffResultPair(list: MutableList<ItemInfo>, result: AutoCompleteResponse = AutoCompleteResponse()): Pair<MutableList<ItemInfo>, DiffUtil.DiffResult> {
    return Flowable.fromArray(list)
            .scan(Pair(mutableListOf(), DiffUtil.calculateDiff(ClassificationDiffCallback(Pair(mutableListOf(), AutoCompleteResponse()), Pair(mutableListOf(), AutoCompleteResponse())))))
            { state: Pair<MutableList<ItemInfo>, DiffUtil.DiffResult>, next: MutableList<ItemInfo> ->
                Pair(next, DiffUtil.calculateDiff(ClassificationDiffCallback(Pair(state.first, result), Pair(next, result))))
            }
            .skip(1)
            .blockingFirst()
}

任何帮助将不胜感激.

推荐答案

DiffUtils比较两个不为空的对象. 因此,如果newListoldList为空,则调用notifyDataSetChanged()而不是调用DiffUtil

DiffUtils compares two objects that is not empty. So if the newList and oldList are either empty call notifyDataSetChanged() instead of calling DiffUtil

我不熟悉您使用的库,但是以前我已经遇到过此类问题.

I'm not familiar with the library you used, but I've already encounter this kind of problem before.

这篇关于DiffUtil回调导致索引超出范围异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆