【问题标题】:Maintain adapter scroll position when calling notifyDataSetChanged and don't reload NetworkImageView调用 notifyDataSetChanged 时保持适配器滚动位置且不重新加载 NetworkImageView
【发布时间】:2026-02-08 03:30:01
【问题描述】:

我有一个 listView 和一个适配器,
我已滚动到列表的中间(假设我们有 100 项我在第 50 项中)
到达那里后,我会从服务器获得一些更新.. 比如说,来自 facebook 的新故事..
A. 我想调用 notifyDataSetChanged() 并保持位置-因为我使用了this code
B. 我正在使用 volley 库中可爱的 NetworkImageView,我希望,当调用 notifyDataSetChanged 时 - 图像不会像现在这样重新加载,因为,(也许那个是我的问题的根源),目前,重新加载图像会导致用户出现某种闪烁(未加载照片)

编辑:

    mQueue = Volley.newRequestQueue(getApplicationContext());// thread pool(4)
    mngr.setRequestQueue(mQueue);

    final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
    mImageLoader = new ImageLoader(mQueue, new ImageCache() {

        private final LruBitmapCache mCache = new LruBitmapCache(maxMemory);

        public void putBitmap(String url, Bitmap bitmap) {

            mCache.put(url, bitmap);
        }

        public Bitmap getBitmap(String url) {

            return mCache.get(url);

        }
    });

我的解决方案:

//      final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
    mImageLoader = new ImageLoader(mQueue, new ImageCache() {

        private final BitmapLruCache mCache = new BitmapLruCache();

        public void putBitmap(String url, Bitmap bitmap) {

            mCache.put(url, bitmap);
        }

        public Bitmap getBitmap(String url) {

            return mCache.get(url);

        }
    });

我使用了下一个bimtap lru缓存实现

public class BitmapLruCache extends LruCache<String, Bitmap> implements ImageCache {
public static int ONE_KILOBYTE = 1024;

public BitmapLruCache() {
    this(getDefaultLruCacheSize());
}

public BitmapLruCache(int maxSize) {
    super(maxSize);
}

public static int getDefaultLruCacheSize() {
    final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / ONE_KILOBYTE);
    final int cacheSize = maxMemory / 8;

    return cacheSize;
}

@Override
protected int sizeOf(String key, Bitmap value) {
    return value.getRowBytes() * value.getHeight() / ONE_KILOBYTE;
}

@Override
public Bitmap getBitmap(String url) {
    return get(url);
}

@Override
public void putBitmap(String url, Bitmap bitmap) {
    put(url, bitmap);
}
}

你们觉得呢?

10 倍

【问题讨论】:

  • 请说明您是如何初始化排球队列、图像加载器和适配器代码的。
  • @Pork 我添加了初始化细节

标签: android android-arrayadapter android-volley networkimageview


【解决方案1】:

我正在使用 volley 库中可爱的 NetworkImageView,我希望在调用 notifyDataSetChanged 时 - 图像不会像现在这样重新加载,因为(也许这就是我的问题的根源),目前,重新加载图像会导致用户出现某种闪烁(未加载照片)

您是否为 ImageLoader 提供了内存缓存?当调用.setImageUrl 时,Volley 首先尝试从您在实例化 ImageLoader 时提供的缓存中获取图像,然后进入磁盘缓存(内置于 Volley),然后进入网络。如果您正确使用了内存缓存,.setImageUrl 应该会立即返回而不会闪烁。我的猜测是您使用了磁盘缓存(不幸的是,在某些教程中推荐使用)。

可以在此处找到内存缓存的示例:https://github.com/ogrebgr/android_volley_examples/blob/master/src/com/github/volley_examples/toolbox/BitmapLruCache.java 然后像这样实例化 ImageLoader:

int cacheSize = 1024 * 1024 * 10; // 10MB Cache
mImageLoader = new ImageLoader(mRequestQueue, new BitmapLruCache(cacheSize));

【讨论】:

  • 嘿@nborrmann,我会调试它,我很确定我已经用 l1(mem) l2(disk) 缓存实现了它
  • @Nils 我面临着类似的问题*.com/questions/30850315/…