探究Android中Listview显示错乱问题
问题
最近在项目中遇到过一个很棘手的问题,就是ListView在滑动后就莫名其妙的显示错乱,网上查阅资料后问题很容易的就解决了,但是对于问题产生的原因仍是一知半解,所以不甘心的我定下心来,狠读源码,终于理清了其中的”奥秘“。
由来
一般的关于Adapter中getView的写法不外乎以下形式:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = mLayout.inflate(R.layout....);
holder = new ViewHolder();
holder.textView = (TextView) convertView
.findViewById(R.id.textview);
... ...
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.textView.setText(mText + position);
return convertView;
}
在Android源码中关于getView方法的实现就是采用的以上形式,如ArrayAdapter等。因为这种写法的好处也是显而易见的,如果该position的convertview曾经被加载过,在数据集合未被改动的前提下,系统会自动将该position的convertview缓存起来,避免重复加载耗费资源。
然后问题就来了,当时我就”自作小聪明“,觉得当convertview==null时只是做了item布局的加载以及相关控件ID的绑定操作,为什么连内容的加载操作也放入其中呢,这样下次加载缓存是就省去内容set的操作了,然后就出现了滑动ListView后数据显示错位的问题-。-。
原因
后来看源码发现,原来AbListView中获取getView()和滑动操作是异步进行的,其中滑动操作在一个FlingRunnable的支线程中运行,所以这就导致了在ListView在滑动时可能已经滑动到了第十行,但可能第二行的数据这时就被直接使用了,这就是导致数据加载错乱的根本原因。
附上源码中对FlingRunnable的注释:
/**
* Responsible for fling behavior. Use {@link #start(int)} to
* initiate a fling. Each frame of the fling is handled in {@link #run()}.
* A FlingRunnable will keep re-posting itself until the fling is done.
*
*/
private class FlingRunnable implements Runnable {
/**
* Tracks the decay of a fling scroll
*/
private final OverScroller mScroller;
... ...
}
解决方法
所以唯一的解决方法就是只在convertview中缓存该ChildView的layout,但ChildView 中的数据必须每次都重新获取并加载。其实ListView数据加载及数据缓存是比较复杂的(几个相关的类加起来上完行=。=),所以以后有机会还是要好好研读源码,这样才能更加透彻的理解原理。
查看原文:www.xyczero.com
探究Android中Listview显示错乱问题的更多相关文章
- Android在ListView显示图片(重复混乱闪烁问题)
Android在ListView显示图片(重复混乱闪烁问题) 1.原因分析 ListView item缓存机制: 为了使得性能更优,ListView会缓存行item(某行相应的View). ListV ...
- Android中ListView控件的使用
Android中ListView控件的使用 ListView展示数据的原理 在Android中,其实ListView就相当于web中的jsp,Adapter是适配器,它就相当于web中的Servlet ...
- android中ListView点击和里边按钮点击不能同时生效问题解决
今天遇到一个问题:android中ListView点击和里边button点击不能同时生效问题解决. 原因是: listView 在开始绘制的时候,系统首先调用getCount()函数,根据他的返回值得 ...
- Android中Listview点击item不变颜色以及设置listselector 无效
Android中Listview点击item不变颜色以及设置listselector 无效 这是同一个问题,Listview中点击item是会变颜色的,因为listview设置了默认的listsele ...
- android中ListView控件&&onItemClick事件中获取listView传递的数据
http://blog.csdn.net/aben_2005/article/details/6592205 本文转载自:android中ListView控件&&onItemClick ...
- Android中ListView无法点击
Android中ListView无法点击 转自:http://xqjay19910131-yahoo-cn.iteye.com/blog/1319502 问题描述: ListView中Item加入 ...
- Android中EditText显示明文与密文的两种方式
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 记录输入框显示.隐藏密码的简单布局以及实现方式. 效果图 代码分析 方式一 /**方式一:*/ private void sh ...
- [安卓基础] 008.Android中的显示单位
*:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } ...
- Android中ListView异步加载图片错位、重复、闪烁问题分析及解决方案
我们在使用ListView异步加载图片的时候,在快速滑动或者网络不好的情况下,会出现图片错位.重复.闪烁等问题,其实这些问题总结起来就是一个问题,我们需要对这些问题进行ListView的优化. 比如L ...
随机推荐
- JDK的下载和安装
检查 检查是否已经安装了JRE,可以在命令行窗口输入"java –version",如果能看到下图所示的信息,则说明已经安装: 检查是否已经安装了JDK,暂时没有发现什么高大上的方 ...
- codevs3945 完美拓印
3945 完美拓印 codevs月赛 第一场 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 黄金 Gold 题目描述 Description 小Q获得了一个神奇的印章,这个印章宽n ...
- Mac下Intellij IDea发布Java Web项目(适合第一次配置Tomcat的家伙们)详解二
准备工作:新建第一个JavaWeb项目 step3 给第一次配置tomcat的家伙们再说一遍如何配置tomcat 3.1 [Run]-[Edit Configurations] 3.2 [Defaul ...
- POJ3617 Best Cow Line
其实是学习参考了算法书的代码,但仍然是我自己写的,有小差别.贪心类型. #include <iostream> using namespace std; int main() { int ...
- Genymotion开始搞起~
简介 一:什么是GenymotionGenymotion是一款完全超越BlueStacks的安卓模拟器,正如它中文官网的介绍:快到极致的Android模拟器.英文官网:http://www.genym ...
- crowd在更改IP后无法登录的问题
org.codehaus.xfire.fault.XFireFault: Client with address "192.168.1.222", and hostname &qu ...
- 小胖学PHP总结1-----PHP的数据类型
PHP一共支持8种原始类型.包含4中标量类型,即:boolean(布尔型).integer(整形).float/double(浮点型)和string(字符串型):两种复合类型,即:array(数组)和 ...
- VMware下安装Ubuntu,那么必须安装VMware-tools,才能获得更好的体验,包括屏幕分辨率、声音、和windows共享剪贴板等等
在VMware下安装Ubuntu,那么必须安装VMware-tools,才能获得更好的体验,包括屏幕分辨率.声音.和windows共享剪贴板等等. 个人觉得安装vmware-tools很重要的几点: ...
- iphone开发中数据持久化之——属性列表序列化(一)
数据持久化是应用程序开发过程中的一个基本问题,对应用程序中的数据进行持久化存储,有多重不同的形式.本系列文章将介绍在iphone开发过程中数据持久化的三种主要形式,分别是属性列表序列号.对象归档化以及 ...
- 此方法显式使用的 CAS 策略已被 .NET Framework 弃用
用vs2008开发的应用程序在vs2012中打开时提示如下: 此方法显式使用的 CAS 策略已被 .NET Framework 弃用.若要出于兼容性原因而启用 CAS 策略,请使用 NetFx40_L ...