volleywinform窗体加载闪烁不会闪烁,是为什么

他的最新文章
他的热门文章
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)查看: 48782|回复: 93
ListView使用imageloader加载图片时,如果刷新,会有闪烁。
签到天数: 14 天连续签到: 1 天[LV.3]偶尔看看II主题帖子e币
ListView使用imageloader加载图片时,如果刷新,之前已经显示的图片,会有闪烁。这个怎么改。谢谢
不是在apdater在加这个判断,adapter中只是对imageview的tag赋值,holder.iv.setTag(url);就行;
判断是在加载图片的方法imageloader中
非常精彩,支持你,加油!
签到天数: 6 天连续签到: 1 天[LV.2]偶尔看看I主题帖子e币
感觉怪怪的:
holder.iv.setTag(url);
if(url.equals(holder.iv.getTag())){
不是在apdater在加这个判断,adapter中只是对imageview的tag赋值,holder.iv.setTag(url);就行;
判断是在加载图片的方法imageloader中
您好,目前我也遇到了这个和您同样得问题,烦请您能指点一下吗?在什么地方设置tag和做判断?&
我支持: 5 有帮助: 5 &
签到天数: 1 天连续签到: 1 天[LV.1]初来乍到主题帖子e币
无代码无真相。没遇到这种情况
签到天数: 6 天连续签到: 1 天[LV.2]偶尔看看I主题帖子e币
这是因为位置错乱了,需要设置一个标记,imageview.setTag(url);然后在imageloader中的imageivew.setImageBitmap()的地方加一个判断;if(url.equals(imageview.getTag()){
imageivew.setImageBitmap();
楼主 我这么写的
怎么还是错乱啊
final ImageView mImageView = (ImageView) convertView.findViewById(R.id.filter_image);
final String imageUrl = AppContext.getAppContext().getDownloadUrl(&
签到天数: 14 天连续签到: 1 天[LV.3]偶尔看看II主题帖子e币
这是因为位置错乱了,需要设置一个标记,imageview.setTag(url);然后在imageloader中的imageivew.setImageB ...
我用的是com.nostra13.universalimageloade的&
<div id="favatar4967138" c网上找了一张图, listview 异步加载图片之所以错位的根本原因是重用了&convertView 且有异步操作.
如果不重用&convertView 不会出现错位现象, 重用&convertView 但没有异步操作也不会有问题。
我简单分析一下:
当重用&convertView 时,最初一屏显示 7 条记录, getView 被调用 7 次,创建了 7 个&convertView.
当 Item1 划出屏幕, Item8 进入屏幕时,这时没有为 Item8 创建新的 view 实例, Item8 复用的是
Item1 的&view&如果没有异步不会有任何问题,虽然&Item8 和 Item1 指向的是同一个 view,但滑到
Item8 时刷上了 Item8 的数据,这时 Item1&的数据和 Item8 是一样的,因为它们指向的是同一块内存,
但 Item1 已滚出了屏幕你看不见。当 Item1 再次可见时这块 view 又涮上了 Item1 的数据。
但当有异步下载时就有问题了,假设 Item1 的图片下载的比较慢,Item8 的图片下载的比较快,你滚上去
使 Item8 可见,这时 Item8 先显示它自己下载的图片没错,但等到 Item1 的图片也下载完时你发现
Item8 的图片也变成了 Item1 的图片,因为它们复用的是同一个 view。 如果 Item1 的图片下载的比
Item8 的图片快, Item1 先刷上自己下载的图片,这时你滑下去,Item8 的图片还没下载完, Item8
会先显示 Item1 的图片,因为它们是同一快内存,当&Item8 自己的图片下载完后 Item8 的图片又刷成
了自己的,你再滑上去使 Item1 可见, Item1 的图片也会和 Item8 的图片是一样的,
因为它们指向的是同一块内存。
最简单的解决方法就是网上说的,给 ImageView 设置一个 tag, 并预设一个图片。
当 Item1 比 Item8 图片下载的快时, 你滚下去使 Item8 可见,这时 ImageView 的 tag 被设成了
Item8 的 URL, 当 Item1 下载完时,由于 Item1 不可见现在的 tag 是 Item8 的 URL,所以不满足条件,
虽然下载下来了但不会设置到 ImageView 上, tag 标识的永远是可见 view 中图片的 URL。
关键代码如下:
// 给 ImageView 设置一个 tag
holder.img.setTag(imgUrl);
// 预设一个图片
holder.img.setImageResource(R.drawable.ic_launcher);
// 通过 tag 来防止图片错位
if (imageView.getTag() != null && imageView.getTag().equals(imageUrl)) {
imageView.setImageBitmap(result);
我参考网上资料写了一个 listview 异步加载图片的 DEMO:
(1) AsyncTask 下载图片
(2) 实现内存、文件二级缓存
&内存缓存使用 LruCache,文件缓存使用 DiskLruCache
* 图片异步加载类
* @author Leslie.Fang
public class AsyncImageLoader {
// 内存缓存默认 5M
static final int MEM_CACHE_DEFAULT_SIZE = 5 * 1024 * 1024;
// 文件缓存默认 10M
static final int DISK_CACHE_DEFAULT_SIZE = 10 * 1024 * 1024;
// 一级内存缓存基于 LruCache
private LruCache&String, Bitmap& memC
// 二级文件缓存基于 DiskLruCache
private DiskLruCache diskC
public AsyncImageLoader(Context context) {
this.context =
initMemCache();
initDiskLruCache();
* 初始化内存缓存
private void initMemCache() {
memCache = new LruCache&String, Bitmap&(MEM_CACHE_DEFAULT_SIZE) {
protected int sizeOf(String key, Bitmap bitmap) {
return bitmap.getByteCount();
* 初始化文件缓存
private void initDiskLruCache() {
File cacheDir = getDiskCacheDir(context, "bitmap");
if (!cacheDir.exists()) {
cacheDir.mkdirs();
diskCache = DiskLruCache.open(cacheDir, getAppVersion(context), 1, DISK_CACHE_DEFAULT_SIZE);
} catch (IOException e) {
e.printStackTrace();
* 从内存缓存中拿
* @param url
public Bitmap getBitmapFromMem(String url) {
return memCache.get(url);
* 加入到内存缓存中
* @param url
* @param bitmap
public void putBitmapToMem(String url, Bitmap bitmap) {
memCache.put(url, bitmap);
* 从文件缓存中拿
* @param url
public Bitmap getBitmapFromDisk(String url) {
String key = hashKeyForDisk(url);
DiskLruCache.Snapshot snapShot = diskCache.get(key);
if (snapShot != null) {
InputStream is = snapShot.getInputStream(0);
Bitmap bitmap = BitmapFactory.decodeStream(is);
} catch (IOException e) {
e.printStackTrace();
return null;
* 从 url 加载图片
* @param imageView
* @param imageUrl
public Bitmap loadImage(ImageView imageView, String imageUrl) {
// 先从内存中拿
Bitmap bitmap = getBitmapFromMem(imageUrl);
if (bitmap != null) {
Log.i("leslie", "image exists in memory");
// 再从文件中找
bitmap = getBitmapFromDisk(imageUrl);
if (bitmap != null) {
Log.i("leslie", "image exists in file");
// 重新缓存到内存中
putBitmapToMem(imageUrl, bitmap);
// 内存和文件中都没有再从网络下载
if (!TextUtils.isEmpty(imageUrl)) {
new ImageDownloadTask(imageView).execute(imageUrl);
return null;
class ImageDownloadTask extends AsyncTask&String, Integer, Bitmap& {
private String imageU
private ImageView imageV
public ImageDownloadTask(ImageView imageView) {
this.imageView = imageV
protected Bitmap doInBackground(String... params) {
imageUrl = params[0];
String key = hashKeyForDisk(imageUrl);
// 下载成功后直接将图片流写入文件缓存
DiskLruCache.Editor editor = diskCache.edit(key);
if (editor != null) {
OutputStream outputStream = editor.newOutputStream(0);
if (downloadUrlToStream(imageUrl, outputStream)) {
editor.commit();
editor.abort();
diskCache.flush();
Bitmap bitmap = getBitmapFromDisk(imageUrl);
if (bitmap != null) {
// 将图片加入到内存缓存中
putBitmapToMem(imageUrl, bitmap);
} catch (IOException e) {
e.printStackTrace();
return null;
protected void onPostExecute(Bitmap result) {
super.onPostExecute(result);
if (result != null) {
// 通过 tag 来防止图片错位
if (imageView.getTag() != null && imageView.getTag().equals(imageUrl)) {
imageView.setImageBitmap(result);
private boolean downloadUrlToStream(String urlString, OutputStream outputStream) {
HttpURLConnection urlConnection = null;
BufferedOutputStream out = null;
BufferedInputStream in = null;
final URL url = new URL(urlString);
urlConnection = (HttpURLConnection) url.openConnection();
in = new BufferedInputStream(urlConnection.getInputStream(), 8 * 1024);
out = new BufferedOutputStream(outputStream, 8 * 1024);
while ((b = in.read()) != -1) {
out.write(b);
return true;
} catch (final IOException e) {
e.printStackTrace();
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
if (out != null) {
out.close();
if (in != null) {
in.close();
} catch (final IOException e) {
e.printStackTrace();
return false;
private File getDiskCacheDir(Context context, String uniqueName) {
String cacheP
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())
|| !Environment.isExternalStorageRemovable()) {
cachePath = context.getExternalCacheDir().getPath();
cachePath = context.getCacheDir().getPath();
return new File(cachePath + File.separator + uniqueName);
private int getAppVersion(Context context) {
PackageInfo info = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
return info.versionC
} catch (NameNotFoundException e) {
e.printStackTrace();
private String hashKeyForDisk(String key) {
String cacheK
final MessageDigest mDigest = MessageDigest.getInstance("MD5");
mDigest.update(key.getBytes());
cacheKey = bytesToHexString(mDigest.digest());
} catch (NoSuchAlgorithmException e) {
cacheKey = String.valueOf(key.hashCode());
return cacheK
private String bytesToHexString(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i & bytes. i++) {
String hex = Integer.toHexString(0xFF & bytes[i]);
if (hex.length() == 1) {
sb.append('0');
sb.append(hex);
return sb.toString();
代码地址:&
如果使用 &Volley 就简单的多了
同一个 URL 请求的重复发送,退出 activity 后队列中请求的 cancel,(上面的 demo 没有处理这两种情况)
图片的缓存等&都不用自己处理了, &Volley 都封装好了。
Volley ListView 异步加载图片 &demo: &
阅读(...) 评论()}

我要回帖

更多关于 glide 加载图片闪烁 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信