前言

RecyclerView是日常开发中最常用的控件之一。一般情况下,我们用它来展示一系列数据的视图。然而在使用过程中,偶尔会出现数据错乱的情况。当然这并不是RecyclerView本身的bug,而是代码编写中的问题。

场景再现

1.先准备一个数据对象

public class TestModel {public TestModel(String description) {this.description = description;}public TestModel(String description, boolean selected) {this.description = description;this.selected = selected;}public String description;public boolean selected;
}

现在要求:将15个TestModel对象展示在RecyclerView中,每个Item包含一个TextView和一个ImageView,其中TextView展示description,当selected = true的时候,ImageView显示为选中状态,否则为未选中状态。

2.准备15个数据,只有第一个model的selected = true。

List<TestModel> models = new ArrayList<>();for (int i = 0; i < 15; i++) {TestModel model = new TestModel(String.format("第%s个Item", i));models.add(model);}models.get(0).selected = true;
<ImageViewandroid:id="@+id/iv_selected"android:layout_width="24dp"android:layout_height="24dp"android:src="@drawable/unselect_backgound"android:layout_marginStart="16dp"/>

给ImageView指定了一张默认的图片,当selected = true时再给ImageView指定选中的图片。RecyclerView.Adapter中的部分代码如下

@Overridepublic void onBindViewHolder(@NonNull TestAdapter.ViewHolder holder, final int position) {TestModel model = models.get(position);holder.mTvDes.setText(model.description);// 注意这里,仅指定了选中状态的图片if (model.selected) {holder.mIvSelected.setImageResource(R.drawable.select_backgound);}}

看下效果


果然,出现了数据错乱的现象 。第12个Item的ImageView中显示了选中图片,打断点可以发现,该Item也并没有执行if(model.selected)的代码。那么为什么会出现这种现象呢?这就涉及到了RecyclerView的复用回收机制。

RecyclerView的复用回收

如上文说到,RecyclerView需要展示15条数据的视图,但并不意味着RecyclerView会真的创建15个ItemView来展示。RecyclerView滚动时,会将已经划出屏幕的ItemView从屏幕上拿下来,放在一个缓存列表中。后续有新的数据需要展示时,从列表中取出一个ItemView用于展示 ,而不是专门重新创建一个ItemView。由于这个ItemView是从缓存中取出的,它依然保留前一次操作后的状态。如果在显示新的数据时,有控件被略过,那么这个控件就会显示上一条数据的状态,从而引起显示上的错乱现象。

解决方案

显示错乱的本质是复用引起了控件保留有上次操作的状态 。那么我们可以从解决复用和更新状态上去着手解决。
1.禁止复用,不过这样就使得性能降低 , 违反了RecyclerView的本质。

// 设置ItemView为不可回收,不能被放入缓存列表,自然无法复用
viewHolder.setIsRecyclable(false);
@Overridepublic int getItemViewType(int position) {// 给每个ItemView指定不同的类型,这样在RecyclerView看来,这些ItemView全是不同的,不能复用return position;}

2.正确的解决方案当然是保证ItemView中的所有控件都能被刷新。尤其是使用了条件表达式的时候。对控件的操作必须要考虑完所有的情况

@Overridepublic void onBindViewHolder(@NonNull TestAdapter.ViewHolder holder, final int position) {TestModel model = models.get(position);holder.mTvDes.setText(model.description);if (model.selected) {holder.mIvSelected.setImageResource(R.drawable.select_backgound);} else {// 保证ImageView控件一定会被操作到holder.mIvSelected.setImageResource(R.drawable.unselect_backgound);}}

Android RecyclerView数据错乱问题相关推荐

  1. android item复用,Android RecyclerView 复用错乱通用解法详解

    写在前面: 在上篇文章中说过对于像 RecyclerView 或者 ListView 等等此类在有限屏幕中展示大量内容的控件,复用的逻辑就是其核心的逻辑,而关于复用导致最常见的 bug 就是复用错乱. ...

  2. android listview数据错乱,AndroidListview 滑动过程中图片显示重复错乱解决方案

    主要分析Android中Listview滚动过程造成的图片显示重复.错乱.闪烁的原因及解决方法,顺便跟进Listview的缓存机制. 1.原因分析 Listview item 缓存机制:为了使得性能更 ...

  3. Android RecyclerView数据展示

    做项目涉及到联网肯定是需要展示网络数据的,RecyclerView+Okhttp展示网络数据虽然很基础很简单,但想想还是写出来让初学者了解一下 ### api ConstantApi 是一级接口 pu ...

  4. android批量删除图片,Android RecyclerView单点、批量数据元素项目item的增加、删除和移动...

    Android RecyclerView单点.批量数据元素项目item的增加.删除和移动 前文附录1,2介绍了基本的Android RecyclerView单点.批量元素项目的更新.现在给出其他比较重 ...

  5. android点赞刷新列表图片闪烁,RecyclerView使用——有效解决刷新数据错乱,图片闪烁,OOM问题...

    做项目时,用到RecyclerView去加载1w张图片,为了防止OOM,需要进行分页预加载;这些完成后测试发现刷新recyclerView会造成数据错乱,在查阅资料得到一下的解决方法. 根据网上资料: ...

  6. Android RecyclerView(八)设置自定义 下拉刷新 与 上拉加载数据

    Android RecyclerView(八)设置下拉刷新 与 上拉加载数据 GitHub 项目源码 CSDN 博客说明 智慧安卓App 文章分析 下拉刷新效果 上拉加载数据效果 1 xml布局文件中 ...

  7. RecyclerView 滑动之后显示数据错乱

    由于RecyclerView的onBindViewHolder()方法,只有在getItemViewType()返回类型不同时才会调用,这点是跟ListView的getView()方法不同的地方,所以 ...

  8. Android实战开发-Kotlin教程(入门篇-RecyclerView数据列表的实现)

    在移动应用开发中,很多时候我们需要去展示数据记录,如电商应用中的商品列表.订单列表等等一系列的数据记录的展示时,我们需要用到Android的列表组件展示这些数据,列表组件应该是我们遇到到比较常见也是必 ...

  9. RecyclerView EditText 数据错乱问题

    因为之前用第三方封装好的适配器 一般情况下也没发现有问题,但是目前也碰到了这个问题  .按照通常方法如果你调用了notifyDataSetChanged 你直接Textwatcher里面直接修改bea ...

最新文章

  1. php生成图片表格自动换行_实用的财务做账表格,点击即可一键生成报表,并自动结转...
  2. Spring Boot2.x-14 使用Prometheus + Grafana 实现可视化的监控
  3. 一致性hash算法使用
  4. 关于mingw编译Qt时无法编译opengl es2(ANGLE)版本的问题
  5. 持续集成部署Jenkins工作笔记0010---创建工程并配置源码管理
  6. 在ubuntu中自定义安装nginx
  7. mysql异构迁移_如何利用数据异构实现多级缓存和数据迁移
  8. python 安卓库_Python 开发安卓Android及IOS应用库Kivy安装尝试
  9. 数学建模论文注意事项
  10. Eclipse解压后打开报错javaw.exe in your current PATH
  11. Js/html格式化在线工具
  12. 东芝发布全系列消费级硬盘
  13. M480 EMAC驱动01-EMAC底层接口
  14. win101909要不要更新_win101909版本千万别更新?win10 1909值得升级吗要不要更新
  15. 解决:el-input添加clearable属性后出现2个×清除图标
  16. 计算机服务器排名,2019服务器CPU天梯图 多路CPU性能排名
  17. 大数据早报:甲骨文公司投资4300万美元在总部建高中 18项全球互联网领先科技成果公布中国占6成 (12.6)
  18. Oracle数据库如何干净的删除
  19. Carthage入门篇-安装和使用
  20. C语言中的移位运算乘法,C语言中 移位操作运算

热门文章

  1. 莫凡的python_周莫凡python
  2. 一个10年程序员给大家的忠告
  3. Matlab App Designer 中表格的操作
  4. PHPWord 导出生成word
  5. 免费的Gif制作工具-录屏、录像
  6. java基础(1~100以内的质数)
  7. 队列详解及java实现
  8. 洛谷 P2258 子矩阵
  9. 计算机wps基础知识试题,计算机一级考试《WPS》精选练习题
  10. 2021-2027全球与中国户外建筑用大理石市场现状及未来发展趋势