热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

安卓使用RecyclerView的notifyItemInserted()的坑

篇首语:本文由编程笔记#小编为大家整理,主要介绍了安卓使用RecyclerView的notifyItemInserted()的坑相关的知识,希望对你有一定的参考价值。

篇首语:本文由编程笔记#小编为大家整理,主要介绍了安卓使用RecyclerView的notifyItemInserted()的坑相关的知识,希望对你有一定的参考价值。






大多数新手经常会碰到:



java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter positionViewHolder**** position=13 id=-1, oldPos=1 ******


我是在这样的场景下出现的这个问题:



scrollToPosition(0) // 快速定位到列表顶部
notifyItemInserted(0) // 插入一条数据

为什么会出现呢?
        是因为在你的 adapter 的 item 改变后,没有及时 notifyItemInserted() 的事情,导致 adapter 里面的数据,和 recyclerView 里面已有的数据出现不一致,就会导致这个问题出现 (此时你的adapter 和 recyclerView 一定总是持有同一个 List )。比如你是用liveData来监听数据的变化,你需要先notify再给adapter赋值,但是我们大多数情况下都是先赋值再notify。正常我们调用 notifyDataSetChanged() 或者 notifyItemRangeChanged() 是不会发生闪退的,但是当我们调用 notifyItemInserted() 这个方法的时候就会出现上述这个奇葩的问题。

怎么解决呢?

        网上大部分的解决方法是catch住这个错误,从而让App不会crash,但是这种方法很明显并没有真正解决这个问题,只是把问题给catch住了,并没有去处理它。

网上的方案:

class DataCheckLinearLayoutManager(
context: Context?
) : LinearLayoutManager(context)
override fun onLayoutChildren(recycler: RecyclerView.Recycler?, state: RecyclerView.State?)
try
super.onLayoutChildren(recycler, state)
catch (e: IndexOutOfBoundsException)
ALog.e("DataCheckLinear", e.message)


        继承 LinearLayoutManager 重写 onLayoutChildren() 方法,去catch住越界的问题。这样写功能上是可以实现的,但是仔细看我们的列表的话,会有一丢丢闪一下的效果。这样就会影响体验。

我认为的正确解决方案:(因为在我的项目里面是可以的)

        我们在给 adpater 的 item 赋值的时候,我们创建一个新的 List ,然后把旧的 List 里面的数据copy进去,这样 adapter 里面的数据和 recyclerView 里面的数据就不是同一个对象了(这里的对象说的是 List 这个对象)这样上面数组越界的问题就解决了。(保证不持有同一个 List 对象,就不会出现数据不一致的情况,因为 List 都不一样了,(数据不一致,指的是同一个 List 对象里面的数据不一致))

总结:当 recyclerView 和 adapter 总是持有同一个对象 List 的时候,最好是保证 adapter 和recyclerView 里面的数据是一致的。建议使用的时候,每次创造一个新的 List 来存储数据(在不影响性能的情况下~)





推荐阅读
  • 本文详细介绍了Android中的坐标系以及与View相关的方法。首先介绍了Android坐标系和视图坐标系的概念,并通过图示进行了解释。接着提到了View的大小可以超过手机屏幕,并且只有在手机屏幕内才能看到。最后,作者表示将在后续文章中继续探讨与View相关的内容。 ... [详细]
  • 本文介绍了一款名为TimeSelector的Android日期时间选择器,采用了Material Design风格,可以在Android Studio中通过gradle添加依赖来使用,也可以在Eclipse中下载源码使用。文章详细介绍了TimeSelector的构造方法和参数说明,以及如何使用回调函数来处理选取时间后的操作。同时还提供了示例代码和可选的起始时间和结束时间设置。 ... [详细]
  • 涉及的知识点-ViewGroup的测量与布局-View的测量与布局-滑动冲突的处理-VelocityTracker滑动速率跟踪-Scroller实现弹性滑动-屏幕宽高的获取等实现步 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • Android开发实现的计时器功能示例
    本文分享了Android开发实现的计时器功能示例,包括效果图、布局和按钮的使用。通过使用Chronometer控件,可以实现计时器功能。该示例适用于Android平台,供开发者参考。 ... [详细]
  • 在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板
    本文介绍了在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板的方法和步骤,包括将ResourceDictionary添加到页面中以及在ResourceDictionary中实现模板的构建。通过本文的阅读,读者可以了解到在Xamarin XAML语言中构建控件模板的具体操作步骤和语法形式。 ... [详细]
  • 带添加按钮的GridView,item的删除事件
    先上图片效果;gridView无数据时显示添加按钮,有数据时,第一格显示添加按钮,后面显示数据:布局文件:addr_manage.xml<?xmlve ... [详细]
  • 微信小程序导航跟随的实现方法
    本文介绍了在微信小程序中实现导航跟随的方法。通过设置导航的position属性和绑定滚动事件,可以实现页面向下滚动到导航位置时,导航固定在页面最上方;页面向上滚动到导航位置时,导航恢复到原始位置;点击导航可以平滑跳转到相应位置。代码示例也给出了具体实现方法。 ... [详细]
  • SmartRefreshLayout自定义头部刷新和底部加载
    1.添加依赖implementation‘com.scwang.smartrefresh:SmartRefreshLayout:1.0.3’implementation‘com.s ... [详细]
  • 前端开发工程师必读书籍有哪些值得推荐?我们直接进入代码复杂版式设置,如下所示,先写些标签,源码在这个链接里面:https://codepen.io/Shadid ... [详细]
  • 开发笔记:图像识别基于主成分分析算法实现人脸二维码识别
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了图像识别基于主成分分析算法实现人脸二维码识别相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 本文由编程笔记#小编为大家整理,主要介绍了css回到顶部按钮相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 本文实例讲述了Android编程实现读取工程中的txt文件功能。分享给大家供大家参考,具体如下:1.众所周知,Android的res文件夹 ... [详细]
  • vue使用
    关键词: ... [详细]
author-avatar
_Yoha
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有