java - 检测到不一致。无效的项目位置 0(偏移量:-1)... RecyclerView 在删除第一个项目时崩溃
问题描述
我正在尝试删除我的RecyclerView
. 使用 livedata 和 diffutil 监视列表的更改。仅当删除第一项RecyclerView
(第 0 个索引)时才会发生崩溃。这似乎与其他相关问题相似。快速滚动等时不会出现此问题。仅在删除第 0 位的项目时才会出现此问题。该项目本身将从数据库中删除。但应用程序崩溃。我尝试从类中追溯错误RecyclerView
:.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5923)
从 RecyclerView.java:
if (offsetPosition < 0 || offsetPosition >= mAdapter.getItemCount()) {
throw new IndexOutOfBoundsException("Inconsistency detected. Invalid item "
+ "position " + position + "(offset:" + offsetPosition + ")."
+ "state:" + mState.getItemCount());
}
偏移位置小于 0 (-1)
完整的错误堆栈:
03-23 08:55:38.739 25087-25087/com.application.essentials E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.application.essentials, PID: 25087
java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid item position 0(offset:-1).state:3 android.support.v7.widget.RecyclerView{41df14f0 VFED.V.. ......ID 0,0-480,606 #7f080084 app:id/recycler_view}, adapter:com.application.essentials.model.AlarmsAdapter@41dd7d80, layout:android.support.v7.widget.LinearLayoutManager@41e10b80, context:com.application.essentials.MainActivity@41d37840
at android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5923)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5858)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5854)
at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2230)
at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1557)
at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1517)
at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:622)
at android.support.v7.widget.RecyclerView.dispatchLayoutStep1(RecyclerView.java:3875)
at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:3639)
at android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:4194)
at android.view.View.layout(View.java:15819)
at android.view.ViewGroup.layout(ViewGroup.java:4884)
at android.support.design.widget.CoordinatorLayout.layoutChild(CoordinatorLayout.java:1183)
at android.support.design.widget.CoordinatorLayout.onLayoutChild(CoordinatorLayout.java:870)
at android.support.design.widget.CoordinatorLayout.onLayout(CoordinatorLayout.java:889)
at android.view.View.layout(View.java:15819)
at android.view.ViewGroup.layout(ViewGroup.java:4884)
at android.support.v4.view.ViewPager.onLayout(ViewPager.java:1775)
at android.view.View.layout(View.java:15819)
at android.view.ViewGroup.layout(ViewGroup.java:4884)
at android.support.design.widget.HeaderScrollingViewBehavior.layoutChild(HeaderScrollingViewBehavior.java:142)
at android.support.design.widget.ViewOffsetBehavior.onLayoutChild(ViewOffsetBehavior.java:41)
at android.support.design.widget.AppBarLayout$ScrollingViewBehavior.onLayoutChild(AppBarLayout.java:1556)
at android.support.design.widget.CoordinatorLayout.onLayout(CoordinatorLayout.java:888)
at android.view.View.layout(View.java:15819)
at android.view.ViewGroup.layout(ViewGroup.java:4884)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)
at android.widget.FrameLayout.onLayout(FrameLayout.java:388)
at android.view.View.layout(View.java:15819)
at android.view.ViewGroup.layout(ViewGroup.java:4884)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1677)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1531)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1440)
at android.view.View.layout(View.java:15819)
at android.view.ViewGroup.layout(ViewGroup.java:4884)...
解决方案
问题出在适配器上。我正在使用setHasStableIds(true); 在适配器构造函数中,以避免“更改项目时闪烁”。我已经覆盖了 2 种方法: public long getItemId(int position) {...} 和 public int getItemViewType(int position) {...}
一旦我删除了以下行,崩溃就消失了,第 0 项也被删除了: setHasStableIds(true); 在构造函数中。但是项目在闪烁。问题在于我在覆盖的方法中返回的内容。下面的代码有问题:
@Override
public long getItemId(int position) {
return position;
}
@Override
public int getItemViewType(int position) {
return position;
}
我返回的位置并不是唯一的。我将项目的 id 作为唯一 ID 返回,问题就消失了。
正确代码:
@Override
public long getItemId(int position) {
return mAlarmEntityList.get(position).getAlarmId();
}
@Override
public int getItemViewType(int position) {
return position;
}
我花了几个小时弄清楚出了什么问题。这些答案帮助了我:RecyclerView 中检测到不一致,如何在滚动时更改 RecyclerView 的内容
如何防止 RecyclerView 项目在 notifyItemChanged(pos) 后闪烁?
希望这对某人有帮助!
推荐阅读
- asp.net-core - OpenIddict:在 ASP.NET Core 应用程序和 WEB.API 应用程序之间共享身份验证
- javascript - script.googleusercontent.com 拒绝连接 webapp href 链接不起作用
- java - sol1 的原始类型 double 没有字段 sol2
- bash - Git:将项目文件夹推送到他们的存储库中
- java - 在 JavaFX 中,当鼠标按下并进入节点时触发事件
- python - 如何在 mediapipe 中获取面部混搭地标的坐标
- docker - 带有 tmpfs 挂载的 Docker BuildKit 构建第二次失败
- java - Android:在创建和显示 AlertDialog 之前获取资源 ID?
- python - 在 Kafka 中消费消息
- haskell - 带有简单断言的 Haskell 脚本