ListView图片错乱原因分析
来源:互联网 发布:csp软件商业绘画 编辑:程序博客网 时间:2024/05/21 21:39
先来看一段代码:
@Overridepublic View getView(finalint position, ViewconvertView, ViewGroup parent) { ViewHolder holder; if (convertView== null) { convertView = mInflater.inflate(R.layout.item, null); holder = new ViewHolder(); holder.appIcon = (ImageView) convertView.findViewById(R.id.appIcon); holder.name = (TextView) convertView.findViewById(R.id.name); holder.size = (TextView) convertView.findViewById(R.id.size); holder.chose = (CheckBox) convertView.findViewById(R.id.chose); convertView.setTag(holder); } else holder = (ViewHolder) convertView.getTag(); MyFile myFile = fileList.get(position); Drawable icon = myFile.icon; if (icon!= null) holder.appIcon.setImageDrawable(myFile.icon); holder.chose.setChecked(myFile.isChose); holder.name.setText(myFile.name); holder.size.setText(myFile.formatSize); holder.chose.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton compoundButton, boolean b) { fileList.get(position).isChose = b; } }); return convertView;}
当你执行下去会发现出现图片错乱的问题,但是当你把if (icon != null)这段注释掉,你会发现突然好了,这是什么原因呢,下面就来分析一下:
a) ListView的复用机制
i. ListView是我们经常使用的一个控件,虽然说都会用,但是却并不一定完全清楚ListView的复用机制,虽然在Android 5.0版本之后提供了RecycleView去替代ListView和GridView,提供了一种插拔式的体验,也就是所谓的模块化。本篇主要针对ListView的复用机制进行探讨,因此就不提RecycleView。
ii. 首先需要说一下RecycleBin的基本原理,这个类也是实现复用的关键类。接着我们需要明确ActiveView的概念,ActiveView其实就是在UI屏幕上可见的视图(onScreenView),也是与用户进行交互的View,那么这些View会通过RecycleBin直接存储到mActivityView数组当中,以便为了直接复用,那么当我们滑动ListView的时候,有些View被滑动到屏幕之外(offScreen) View,那么这些View就成为了ScrapView,也就是废弃的View,已经无法与用户进行交互了,这样在UI视图改变的时候就没有绘制这些无用视图的必要了。他将会被RecycleBin存储到mScrapView数组当中,但是没有被销毁掉,目的是为了二次复用,也就是间接复用。当新的View需要显示的时候,先判断mActivityView中是否存在,如果存在那么我们就可以从mActivityView数组当中直接取出复用,也就是直接复用,否则的话从mScrapView数组当中进行判断,如果存在,那么二次复用当前的视图,如果不存在,那么就需要inflate View了。
iii . 可能很多读者都不太明白直接复用到底是怎么个过程,举个例子,比如说我们ListView一页可以显示10条数据,那么我们在这个时候滑动一个Item的距离,也就是说把position = 0的Item移除屏幕,将position = 10 的Item移入屏幕,那么position = 1的Item是不是就直接能够从mActivityView数组中拿到呢?这是可以的,我们在第一次加载Item数据的时候,已经将position = 0~9的Item加入到了mActivityView数组当中,那么在第二次加载的时候,由于position = 1 的Item还是ActivityView,那么这里就可以直接从数组中获取,然后重新布局。这里也就表示的是Item的直接复用。简单来说就是如果对应的position的item在当前显示的界面就相当于移动一下位置。
b) 上面是理论基础部分,接着结合代码分析一下,首先我们代码复用了“convertView”,这个就是起因,正如上面介绍的,“convertView”是来自于mScrapView或者mActivityView数组,因此每次滑动时最上面一个item会消失在屏幕中,最下面一个会出现在屏幕中。然后ListView会复用上一个消失的item,这个item的各种值此刻还是保留的,接着就是上面问题的解释了,为什么去掉了if (icon!= null)这段就不会图片错乱了。因为有这个条件我们当前的item就可能不会重新设置ImageView的图片,导致它还是上一次的图片
c) 因此有个结论,为了防止图片错乱,有两个办法,一个是基础部分,就是item的每个控件都要重新赋值,不管值是否为空;另一个就是设置Tag,这种是针对异步加载图片情况处理的
- ListView图片错乱原因分析
- listview数据错乱、重复的原因分析与解决方案
- listView图片错乱
- listview图片错乱问题解决
- ListView图片错乱
- listview 加载图片错乱(错位)
- ListView图片加载错乱01
- ListView图片加载错乱02
- ListView图片加载错乱03
- 解决ListView异步加载图片错乱问题
- 解决ListView异步加载图片错乱问题
- 解决ListView异步加载图片错乱问题
- 解决ListView异步加载图片错乱问题 .
- android listview 加载图片错乱(错位)(2)
- android listview 加载图片错乱(错位)
- 自定义ListView滚动时,图片显示错乱
- ListView数据错乱--分析及解决
- 【Tech-Android-View】ListView滚动中显示图片错乱
- angular 路由拦截
- HTML5与原生开发孰优孰劣?这场战争是时候结束了
- 每天一点Linux命令
- vue.js实现用户评论、登录、注册、及修改用户部分信息功能代码。
- jsp跳转servlet以后转发或重定向以后css和js样式消失。页面布局混乱
- ListView图片错乱原因分析
- CodeForces 731 C.Socks(贪心+并查集)
- C++TinyXml读取解析xml文件
- ElasticSearch--以属性为中心的查询
- Spring Boot对Web开发的支持
- Spring Aop中的advisor、advice、pointcut
- FGD(一)
- 设计模式之---适配器模式
- Swiper滑动Html5手机浏览器自适应