当前位置: 首页 > 知识库问答 >
问题:

检测到不一致。无效的视图保持器适配器位置

葛承德
2023-03-14
class Adapter(private val adapterType: Int, private val clickListener: GalleryHolder.ClickListener) : SelectableAdapter<Adapter.GalleryHolder>() {
    val objectArrayList: ArrayList<String> = ArrayList()
    private var emptyView: View? = null

    companion object {
        const val IMAGE = 0
        const val VIDEO = 1
    }

    fun addAll(items: ArrayList<String>) {
        objectArrayList.addAll(items)
        notifyItemRangeInserted(0, objectArrayList.size)
    }

    fun clear() {
        val size = objectArrayList.size
        notifyItemRangeRemoved(0, size)
        objectArrayList.clear()
    }

    override fun getItemCount(): Int {
        return objectArrayList.size
    }

    fun setEmptyView(emptyView: View) {
        this.emptyView = emptyView
    }

    fun toogleEmptyView() {
        if (objectArrayList.size == 0) emptyView!!.visibility = View.VISIBLE
        else emptyView!!.visibility = View.GONE
    }


    fun removeItems(positions: MutableList<Int>) {
        positions.sortWith(Comparator { lhs, rhs -> rhs!! - lhs!! })

        while (positions.isNotEmpty()) {
            if (positions.size == 1) {
                removeItem(positions[0])
                positions.removeAt(0)
            } else {
                var count = 1
                while (positions.size > count && positions[count] == positions[count - 1] - 1)
                    ++count

                if (count == 1)
                    removeItem(positions[0])
                else
                    removeRange(positions[count - 1], count)

                if (count > 0) positions.subList(0, count).clear()
            }
        }

        toogleEmptyView()
    }

    private fun removeRange(positionStart: Int, itemCount: Int) {
        for (i in 0 until itemCount) objectArrayList.removeAt(positionStart)
        notifyItemRangeRemoved(positionStart, itemCount)
    }

    private fun removeItem(position: Int) {
        objectArrayList.removeAt(position)
        notifyItemRemoved(position)
    }


    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): GalleryHolder {
        var layout = R.layout.item
        if (adapterType == VIDEO) layout = R.layout.item_video

        val view = LayoutInflater.from(parent.context).inflate(layout, parent, false)
        return GalleryHolder(view)
    }

    override fun onBindViewHolder(holder: GalleryHolder, position: Int) {
        if (adapterType == VIDEO)
            Glide.with(holder.img)
                    .asBitmap()
                    .apply(RequestOptions()
                            .frame(TimeUnit.SECONDS.toMicros(2))
                            .diskCacheStrategy(DiskCacheStrategy.ALL))
                    .load(objectArrayList[holder.adapterPosition])
                    .transition(BitmapTransitionOptions.withCrossFade())
                    .into(holder.img)
        else
            Glide.with(holder.img)
                    .asBitmap()
                    .apply(RequestOptions().diskCacheStrategy(DiskCacheStrategy.ALL))
                    .load(objectArrayList[holder.adapterPosition])
                    .transition(BitmapTransitionOptions.withCrossFade())
                    .into(holder.img)

        // Highlight the item if it's selected
        holder.selectedOverlay.setBackgroundColor(ColorUtils.setAlphaComponent(HelperMethods.getPrimaryColor(holder.selectedOverlay.context), 175))
        holder.selectedOverlay.visibility = if (isSelected(holder.adapterPosition)) View.VISIBLE else View.INVISIBLE
        holder.itemView.setOnClickListener { clickListener.onItemClicked(holder.adapterPosition) }
        holder.itemView.setOnLongClickListener { clickListener.onItemLongClicked(holder.adapterPosition) }
    }

    class GalleryHolder internal constructor(itemView: View) : RecyclerView.ViewHolder(itemView) {
        internal val img: ImageView = itemView.findViewById(R.id.img)
        internal val selectedOverlay: RelativeLayout = itemView.findViewById(R.id.parent)

        interface ClickListener {
            fun onItemClicked(position: Int)
            fun onItemLongClicked(position: Int): Boolean
        }
    }
}
Fatal Exception: java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter positionViewHolder{41bc02f0 position=116 id=-1, oldPos=0, pLpos:0 scrap [attachedScrap] tmpDetached not recyclable(1) no parent} androidx.recyclerview.widget.RecyclerView{41dc3c18 VFED.... .F....ID 0,0-480,606 #7f090125 app:id/recycler_view}, adapter:c.g.a.b.a@41df0ba8, layout:androidx.recyclerview.widget.GridLayoutManager@41d8ca08, context:com.example.MainActivity@41cc4090
   at androidx.recyclerview.widget.RecyclerView$Recycler.setViewCacheExtension(RecyclerView.java:79)
   at androidx.recyclerview.widget.RecyclerView$Recycler.validateViewHolderForOffsetPosition + 5901(RecyclerView.java:5901)
   at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline + 6084(RecyclerView.java:6084)
   at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition + 6044(RecyclerView.java:6044)
   at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition + 6040(RecyclerView.java:6040)
   at androidx.recyclerview.widget.LinearLayoutManager$LayoutState.next + 2303(LinearLayoutManager.java:2303)
   at androidx.recyclerview.widget.GridLayoutManager.layoutChunk + 561(GridLayoutManager.java:561)
   at androidx.recyclerview.widget.LinearLayoutManager.onAnchorReady(LinearLayoutManager.java:105)
   at androidx.recyclerview.widget.LinearLayoutManager.fill + 1587(LinearLayoutManager.java:1587)
   at androidx.recyclerview.widget.LinearLayoutManager.onLayoutChildren + 665(LinearLayoutManager.java:665)
   at androidx.recyclerview.widget.GridLayoutManager.onLayoutChildren + 170(GridLayoutManager.java:170)
   at androidx.recyclerview.widget.RecyclerView.onScrollStateChanged(RecyclerView.java:74)
   at androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep1 + 4014(RecyclerView.java:4014)
   at androidx.recyclerview.widget.RecyclerView.dispatchLayout + 3778(RecyclerView.java:3778)
   at androidx.recyclerview.widget.RecyclerView.onLayout + 4333(RecyclerView.java:4333)
   at android.view.View.layout + 15602(View.java:15602)
   at android.view.ViewGroup.layout + 4880(ViewGroup.java:4880)
   at android.widget.RelativeLayout.onLayout + 1055(RelativeLayout.java:1055)
   at android.view.View.layout + 15602(View.java:15602)
   at android.view.ViewGroup.layout + 4880(ViewGroup.java:4880)
   at androidx.swiperefreshlayout.widget.SwipeRefreshLayout.onLayout + 625(SwipeRefreshLayout.java:625)
   at android.view.View.layout + 15602(View.java:15602)
   at android.view.ViewGroup.layout + 4880(ViewGroup.java:4880)
   at android.widget.FrameLayout.layoutChildren + 453(FrameLayout.java:453)
   at android.widget.FrameLayout.onLayout + 388(FrameLayout.java:388)
   at android.view.View.layout + 15602(View.java:15602)
   at android.view.ViewGroup.layout + 4880(ViewGroup.java:4880)
   at androidx.viewpager.widget.ViewPager.onLayout + 1775(ViewPager.java:1775)
   at android.view.View.layout + 15602(View.java:15602)
   at android.view.ViewGroup.layout + 4880(ViewGroup.java:4880)
   at android.widget.LinearLayout.setChildFrame + 1677(LinearLayout.java:1677)
   at android.widget.LinearLayout.layoutVertical + 1531(LinearLayout.java:1531)
   at android.widget.LinearLayout.onLayout + 1440(LinearLayout.java:1440)
   at android.view.View.layout + 15602(View.java:15602)
   at android.view.ViewGroup.layout + 4880(ViewGroup.java:4880)
   at androidx.drawerlayout.widget.DrawerLayout.onLayout + 1231(DrawerLayout.java:1231)
   at android.view.View.layout + 15602(View.java:15602)
   at android.view.ViewGroup.layout + 4880(ViewGroup.java:4880)
   at android.widget.FrameLayout.layoutChildren + 453(FrameLayout.java:453)
   at android.widget.FrameLayout.onLayout + 388(FrameLayout.java:388)
   at android.view.View.layout + 15602(View.java:15602)
   at android.view.ViewGroup.layout + 4880(ViewGroup.java:4880)
   at android.widget.FrameLayout.layoutChildren + 453(FrameLayout.java:453)
   at android.widget.FrameLayout.onLayout + 388(FrameLayout.java:388)
   at android.view.View.layout + 15602(View.java:15602)
   at android.view.ViewGroup.layout + 4880(ViewGroup.java:4880)
   at android.widget.FrameLayout.layoutChildren + 453(FrameLayout.java:453)
   at android.widget.FrameLayout.onLayout + 388(FrameLayout.java:388)
   at android.view.View.layout + 15602(View.java:15602)
   at android.view.ViewGroup.layout + 4880(ViewGroup.java:4880)
   at android.widget.LinearLayout.setChildFrame + 1677(LinearLayout.java:1677)
   at android.widget.LinearLayout.layoutVertical + 1531(LinearLayout.java:1531)
   at android.widget.LinearLayout.onLayout + 1440(LinearLayout.java:1440)
   at android.view.View.layout + 15602(View.java:15602)
   at android.view.ViewGroup.layout + 4880(ViewGroup.java:4880)
   at android.widget.FrameLayout.layoutChildren + 453(FrameLayout.java:453)
   at android.widget.FrameLayout.onLayout + 388(FrameLayout.java:388)
   at android.view.View.layout + 15602(View.java:15602)
   at android.view.ViewGroup.layout + 4880(ViewGroup.java:4880)
   at android.view.ViewRootImpl.performLayout + 2256(ViewRootImpl.java:2256)
   at android.view.ViewRootImpl.performTraversals + 2010(ViewRootImpl.java:2010)
   at android.view.ViewRootImpl.doTraversal + 1234(ViewRootImpl.java:1234)
   at android.view.ViewRootImpl$TraversalRunnable.run + 6301(ViewRootImpl.java:6301)
   at android.view.Choreographer$CallbackRecord.run + 813(Choreographer.java:813)
   at android.view.Choreographer.doCallbacks + 613(Choreographer.java:613)
   at android.view.Choreographer.doFrame + 583(Choreographer.java:583)
   at android.view.Choreographer$FrameDisplayEventReceiver.run + 799(Choreographer.java:799)
   at android.os.Handler.handleCallback + 733(Handler.java:733)
   at android.os.Handler.dispatchMessage + 95(Handler.java:95)
   at android.os.Looper.loop + 146(Looper.java:146)
   at android.app.ActivityThread.main + 5511(ActivityThread.java:5511)
   at java.lang.reflect.Method.invokeNative(Method.java)
   at java.lang.reflect.Method.invoke + 515(Method.java:515)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run + 1283(ZygoteInit.java:1283)
   at com.android.internal.os.ZygoteInit.main + 1099(ZygoteInit.java:1099)
   at dalvik.system.NativeStart.main(NativeStart.java)

如有任何帮助,不胜感激。

共有1个答案

韦鸣
2023-03-14

出现错误是因为系统试图查找一个列表元素,该元素已经不存在了,因为您在以前的循环迭代中删除了它。

请确保在迭代列表项或访问列表时不从列表中移除元素。

只需为要删除的元素创建一个单独的列表,并在循环完成后删除它们。

 类似资料:
  • 我有一个RxJava2可观察到,它接受两个列表,为它们计算diff结果,并将此数据发送到适配器。适配器在主线程上调度更新。 我检测到不一致。在某些设备上有时出现无效视图保持器适配器PositionViewHolder错误。我也搞不清我的代码出了什么问题。最小SDK 21,目标SDK 26,RecyclerView版本为26.0.0。我知道扩展LinearLayoutManager和静默捕获此错误的

  • 我有一个“回收者”视图,它在除三星以外的所有设备上都能完美运行。在三星上,我明白了 JAVAlang.IndexOutOfBoundsException:检测到不一致。视图保持架适配器位置无效视图保持架 当我从另一个活动的“回收者”视图返回片段时。 适配器代码: 例外: 我该怎么解决这个问题?

  • 我已经开始在Crashlytics上报道这次坠机事件。我不知道如何复制它,但它似乎都是内部的代码。我认为这来自于我的<代码>回收视图</代码>它从未真正改变过。用户可以刷新它,但随后会替换所有项,并调用。

  • 我们的QA检测到了一个bug:当旋转Android设备(Droid Turbo)时,发生了以下与RecyclerView相关的崩溃: java.lang.IndexOutOfBoundsException:检测到不一致。无效的物料位置%2(偏移量:%2)。状态:%3 对我来说,这看起来像是RecyclerView内部的一个内部错误,因为我想不出这是由我们的代码直接导致的任何方式... 有人遇到过这

  • 致命异常:检测到java.lang.IndexOutOfBoundsException不一致。无效的物料位置5(偏移量:5)。状态:24 这种撞车的情况太多了!!! 我在布料上弄到的。 DateList是涉及RecyclerView片段: callToServer(带有假输入)首先清除键列表,然后填充它。几毫秒后,将调用callToServer(具有true输入)来再次清除keyList,并填充新

  • 同时,我编写了一个自定义适配器,可以添加页眉和页脚。我使用了这个适配器,并添加了一个加载更多页脚,这样我的列表在向下滚动时可以加载更多。这导致了一点:我的列表,可以加载更多,将始终包含至少一个项目(加载更多页脚)。 为避免误解,下面的“项目”一词将特别表示项目不是页眉或页脚。 然后,当我通过diffUtil将项目从n(n>0)项通知为零时,问题发生了,我的应用程序崩溃。 值得一提的是,如果我使用没

  • 我的应用程序中有回收器视图。UI类似于Google Play Store应用程序。它有两个视图寻呼机和项目的列表和网格以交替的方式。所有数据都是从web服务中提取的,并在两个API调用中被分叉。列表和网格的数据是从另一个API填充的。问题是,当我快速滚动recyclerview时,我会遇到这种崩溃。滚动recyclerview时,用于在列表/网格中加载数据的API调用来自。阅读了许多关于这个主题的