最新内容建议直接访问原文:Android ListView滑动过程中图片显示重复错乱闪烁问题解决
主要分析Android ListView滚动过程中图片显示重复、错乱、闪烁的原因及解决方法,顺带提及ListView的缓存机制。
1、原因分析
ListView item缓存机制:为了使得性能更优,ListView会缓存行item(某行对应的View)。ListView通过adapter的getView函数获得每行的item。滑动过程中,
a. 如果某行item已经滑出屏幕,若该item不在缓存内,则put进缓存,否则更新缓存;
b. 获取滑入屏幕的行item之前会先判断缓存中是否有可用的item,如果有,做为convertView参数传递给adapter的getView。
更具体可见源代码ListView.obtainView。
这样,如下的getView写法就可以充分利用缓存大大提升ListView的性能。即便上万个行item,最多inflate的次数为n,n为一屏最多显示ListView 行item的个数。
a. 行item图片显示重复
这个显示重复是指当前行item显示了之前某行item的图片。
比如ListView滑动到第2行会异步加载某个图片,但是加载很慢,加载过程中listView已经滑动到了第14行,且滑动过程中该图片加载结束,第2行已不在屏幕内,根据上面介绍的缓存原理,第2行的view可能被第14行复用,这样我们看到的就是第14行显示了本该属于第2行的图片,造成显示重复。
b. 行item图片显示错乱
这个显示错乱是指某行item显示了不属于该行item的图片。
比如ListView滑动到第2行会异步加载某个图片,但是加载很慢,加载过程中listView已经滑动到了第14行,第2行已不在屏幕内,根据上面介绍的缓存原理,第2行的view可能被第14行复用,第14行显示了第2行的View,这时之前的图片加载结束,就会显示在第14行,造成错乱。
c. 行item图片显示闪烁
上面b的情况,第14行图片又很快加载结束,所以我们看到第14行先显示了第2行的图片,立马又显示了自己的图片进行覆盖造成闪烁错乱。
2、解决方法
通过上面的分析我们知道了出现错乱的原因是异步加载及对象被复用造成的,如果每次getView能给对象一个标识,在异步加载完成时比较标识与当前行item的标识是否一致,一致则显示,否则不做处理即可。
下面以使用ImageCache为ListView提供图片获取缓存为例,ListView中强烈推荐使用ImageCache。
首先在listview adapter的getView中添加
@Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder; if (convertView == null) { convertView = inflater.inflate(R.layout.list_item, null); holder = new ViewHolder(); …… convertView.setTag(holder); } else { holder = (ViewHolder)convertView.getTag(); } …… // add tag for image, to compare it when image loaded finish imageView.setTag(imageUrl); // if not in cache, restore default if (!Cache.ICON_CACHE.get(imageUrl, imageView)) { imageView.setImageDrawable(null); } }
其中setTag表示设置标识,方便下面进行标志比对
if (!Cache.ICON_CACHE.get(imageUrl, imageView))
Cache.ICON_CACHE为ImageCache的实例,表示如果不在缓存内则设置drawable为null(当然你可以可以设置为你自己的默认资源),防止显示了之前某个行item的图片,解决了a. 行item图片显示重复问题。
在ImageCache的OnImageCallbackListener的onImageLoaded函数中添加
public void onImageLoaded(String imageUrl, Drawable imageDrawable, View view, boolean isInCache) { // can be another view child, like textView and so on if (view != null && imageDrawable != null) { ImageView imageView = (ImageView)view; // add tag judge, avoid listView cache and so on String imageUrlTag = (String)imageView.getTag(); if (ObjectUtils.isEquals(imageUrlTag, imageUrl)) { imageView.setImageDrawable(imageDrawable); } } };
在上面用String imageUrlTag = (String)imageView.getTag();取得之前设置的tag,然后和当前的url进行比较,如果相等则显示,解决了b. 行item图片显示错乱,c. 行item图片显示错乱的两个问题。其中ObjectUtils可见ObjectUtils@Github.
其他异步加载过程解决原理类似。
你可能还感兴趣:
Android公共库(缓存 下拉ListView 下载管理Pro 静默安装 root运行 Java公共类)
Android系统下载管理DownloadManager功能介绍及使用示例
相关推荐
总结起来,要解决ListView滑动过程中图片显示异常的问题,开发者需要理解ListView的缓存机制,并在处理异步加载时,正确地绑定和更新View的状态,以确保每个列表项都准确地显示其对应的数据。通过上述方法,可以有效...
网上大部分都是写的item上面显示静态图片的例子,我这个是解决显示动态图片时复用导致的动画显示错乱问题。问题描述:假如一屏可以显示10个item项,如果第一个正在播放动画,此时往下滚动,当第一个item不可见时会...
在Android开发中,ListView是广泛使用的组件,用于展示大量数据列表。然而,它在处理大量图片时容易引发性能问题,如内存溢出(OOM)、图片闪烁等。本篇将深入探讨如何对ListView进行优化,以及如何实现图片的异步...
在Android开发中,ListView是一种常用的组件,用于展示大量的列表数据。滑动分页技术是当用户滚动到底部时,自动加载更多数据的功能,这在处理大量数据时非常实用,可以提高用户体验并节省流量。本篇文章将详细讲解...
然而,当ListView内部嵌套CheckBox等可交互组件时,常常会遇到一些问题,特别是滑动过程中选中状态错乱的现象。这个问题主要是由于ListView的复用机制导致的,即ListView在滚动时会复用已滑出屏幕的列表项,如果不...
在Android开发中,ListView是一种常用的组件,用于展示可滚动的多行数据,通常用于列表形式的数据展示。然而,开发者在实现ListView加载图片时可能会遇到图片错乱或错位的问题,这通常是由于不当的图片加载策略或者...
在Android开发中,ListView是一种常用的组件,用于展示大量的列表数据。ListView的优势在于它可以高效地管理内存,只加载屏幕可见的视图,从而节省系统资源。本篇将详细讲解如何实现ListView的滑动自动加载功能,即...
Android listview viewpager 滑动 跳动 冲突解决 ListView中嵌套ViewPage有或者滑动手势冲突解决 blog 地址 : http://blog.csdn.net/aaawqqq/article/details/43824631
在Android开发中,ListView是一种常用的组件,用于展示大量的列表数据。`Android listView选项滑动效果`是指通过增强ListView的功能,使每个列表项可以左右滑动,通常用于实现更多的交互操作,比如滑动删除、切换...
解决复杂布局,scrollview嵌套ListView滑动性能的问题,提供下拉刷新和暴露对外操作listview控件UI的方法,同步博文:http://blog.csdn.net/qq_28690547/article/details/50792439
通过以上步骤,我们可以实现一个动态隐藏和显示标题的功能,同时解决滑动过程中的空白问题。在项目中,可以对代码进行适当的优化和调整,以适应不同的需求和设计。提供的`HideTitleDemo`示例代码应该包含了完整的...
在Android应用开发中,UI设计和用户体验是至关重要的部分,特别是在构建列表视图(ListView)时。本知识点主要探讨如何实现“滑动ListView时标题置顶”和“ListView吸顶效果”,以及如何使安卓系统状态栏透明化。这些...
然而,在ListView中嵌套多个EditText时,常常会遇到一个问题,即用户在EditText中输入内容时,ListView滚动时导致显示混乱,原本输入的位置与EditText不匹配,这被称为“EditText焦点错乱”或“ListView复用机制问题...
在Android中实现ListView滑动刷新通常有两种方式:一种是使用SwipeRefreshLayout,这是Android SDK提供的官方解决方案;另一种是自定义适配器和头部视图,通过监听ListView的滚动事件来触发刷新。 1. ...
本篇文章将详细介绍如何在Android中实现ListView的滑动删除功能,以及如何处理View的滑动事件。 首先,实现ListView的滑动删除通常需要借助于SwipeRefreshLayout或者侧滑库如SlideToDismiss。SwipeRefreshLayout...
首先,我们要了解Android中的SwipeListView。SwipeListView是基于ListView的一个扩展,它提供了滑动触发事件的能力。47deg-android-swipelistview-25d1b3f这个库就是实现这一功能的一个开源项目,它允许用户通过左右...
在Android开发中,ListView是一种常用的组件,用于展示大量的列表数据。"android listview滑动到底部加载数据"这个主题涉及到一个常见的功能需求:无限滚动或称为“上拉加载更多”。这种设计模式允许用户在滚动到...
Android ListView 控件显示数据库中...本文总结了 Android ListView 控件显示数据库中图片的过程,涉及到 SimpleAdapter、ViewBinder、数据库操作、ListView 控件的点击事件、图片的显示等知识点,希望对读者有所帮助。
- ListView是Android中的一个视图容器,通过Adapter(适配器)机制将数据与视图进行绑定,实现数据显示。 - 为了提高性能,ListView采用了回收复用View(convertView)的机制,只有当前可见及即将可见的item才会被...