我最近在一些设备中遇到了上述崩溃,不知道是什么触发了它。
一些答案建议扩展LayoutManager并使异常保持沉默,但我宁愿为此找到一个永久有效的解决方案,一些建议清除我正在做的适配器列表,但仍然会崩溃。
这是Adapter类-
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)
任何帮助将不胜感激。
答案 0 :(得分:0)
出现此错误是因为系统试图查找不再存在的list元素,因为您已在较早的循环迭代中将其删除。
确保仍在遍历列表项或访问列表时不要从列表中删除元素。
只需为要删除的元素创建一个单独的列表,然后在循环完成后将其删除。
答案 1 :(得分:0)
您正在尝试通知尚未删除的已删除项目。
您需要先清除列表 objectArrayList.clear()
,然后是 notifyItemRangeRemoved(0, size)
。