最近线上在展示recyclerview界面的时候出现下标越界的问题
java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid item position 6(offset:6).
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:3300)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:3258)
at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:1803)
at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1302)
at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1265)
at android.support.v7.widget.LinearLayoutManager.scrollBy(LinearLayoutManager.java:1093)
at android.support.v7.widget.LinearLayoutManager.scrollVerticallyBy(LinearLayoutManager.java:956)
at android.support.v7.widget.RecyclerView$ViewFlinger.run(RecyclerView.java:2715)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:725)
at android.view.Choreographer.doCallbacks(Choreographer.java:555)
at android.view.Choreographer.doFrame(Choreographer.java:524)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:711)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4921)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1027)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:794)
at dalvik.system.NativeStart.main(Native Method)
于是用了网上的一些方法尝试
方法一
重写layoutManager,在onLayoutChildren方法中抓异常
class WrapperGridLayoutManager : GridLayoutManager {
constructor(context: Context?, attrs: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(
context,
attrs,
defStyleAttr,
defStyleRes
)
constructor(context: Context?, spanCount: Int) : super(context, spanCount)
constructor(context: Context?, spanCount: Int, orientation: Int, reverseLayout: Boolean) : super(
context,
spanCount,
orientation,
reverseLayout
)
override fun onLayoutChildren(recycler: RecyclerView.Recycler?, state: RecyclerView.State) {
try {
super.onLayoutChildren(recycler, state)
} catch (e: Exception) {
e.printStackTrace()
}
}
}
这个方法试过之后还是不好用
方法二
list数据在clear之后调用notifyItemRangeRemoved方法,在调用addAll方法之后在通过adapter调用notifyItemRangeChanged
//下面是伪代码
val size = searchList.size
searchList.clear()
adapter?.notifyItemRangeRemoved(0,size)
searchList.addAll(viewModel.getSearch())
adapter?.notifyItemRangeChanged(0,viewModel.getSearch().size)
这个方法还是会导致页面崩溃
最后用了notifyDataSetChanged方法,注意:在list数据clear之后也需要调用这个方法
//错误
searchResult.clear()
searchResult.addAll(viewModel.search(content))
searchList.adapter?.notifyDataSetChanged()
//不知道是否正确,但是测试挺久页面不崩溃了
searchResult.clear()
searchList.adapter?.notifyDataSetChanged()
searchResult.addAll(viewModel.search(content))
searchList.adapter?.notifyDataSetChanged()