【问题标题】:What is the best practice to pre catch images for android list?为 android 列表预先捕获图像的最佳做法是什么?
【发布时间】:2016-04-21 09:17:14
【问题描述】:

目前我正在加载图像,即使用户没有滚动查看,所以当他将在列表承包商上从 Picasso 缓存中更快地加载图像时

private void createImageCatch(ArrayList<Article> items) {
    for (int i = 0; i < items.size(); i++) {
            Article article = (Article) items.get(i);
            if (article.getImageUrl() != null
                    && article.getImageUrl().length() > 0)
                Picasso.with(mContext).load(article.getImageUrl())
                        .fetch();
    }
}

这是完美的工作,即使用户快速滚动图像也准备好了,但这是最好的方法吗?

改进更新 - 添加静态布尔值以确保此方法仅调用一次,如果图像是在服务器端添加的,这对于滚动时加载的少量图像来说没什么大不了的,只要它们必须已经在缓存中。

【问题讨论】:

  • 取决于 ImageView 大小 && ListView 项目数
  • 我不认为这是正确的方法,预取你不需要的数据是一种矫枉过正的方式。
  • 小图,30左右。我也没有看到这是最好的方法,这就是我问的原因。我想避免在很短的时间内出现空白图像
  • 短时间的空白图片对用户来说没什么大不了的,除了可以使用占位符图片。
  • 这是一个非常大的应用程序,我希望它尽可能流畅......

标签: android caching picasso android-image


【解决方案1】:

您是否考虑过使用Volley library?它有一个特殊的ImageView 可以为你下载和缓存图片。

将 XML 中的 ImageView 替换为如下内容:

<com.android.volley.toolbox.NetworkImageView
    android:id="@+id/photo"
    android:layout_width="48dp"
    android:layout_height="48dp"
    android:layout_alignParentBottom="true"
    android:layout_alignParentTop="true"
    android:layout_marginRight="6dip"
 />

然后加载你的图片

NetworkImageView photo = (NetworkImageView)view.findViewById(R.id.photo);
photo.setImageUrl("http://someurl.com/image.png", mImageLoader);

你确实需要设置你的ImageLoader,所以创建一些字段:

private RequestQueue mRequestQueue;
private ImageLoader mImageLoader;

并在您的onCreate 中初始化它们:

mRequestQueue = Volley.newRequestQueue(context);
mImageLoader = new ImageLoader(mRequestQueue, new ImageLoader.ImageCache() {
    private final LruCache<String, Bitmap> mCache = new LruCache<String, Bitmap>(10);
    public void putBitmap(String url, Bitmap bitmap) {
        mCache.put(url, bitmap);
    }
    public Bitmap getBitmap(String url) {
        return mCache.get(url);
    }
});

来源:Setting up the Android Google Volley ImageLoader for NetworkImageView

【讨论】:

  • 但是毕加索也是为我做的,所以有什么不同?我也考虑过 Glide,但如果我了解 current ,结果将是相同的。我想也许可以做我的解决方案,但只适用于当前位置附近的图像。如果用户在 10 位,我可能只会一次获得下一张图片。我会更新的。
【解决方案2】:

如果你想重复使用约30张小图像,你可以将它们作为Bitmaps的软引用保存在内存中,并在离开Fragment或Activity后将它们全部回收到ListView。


例如,您的ImageView 大小为 55dp x 55dp,并且有 30 行图片。


显示管理器:

public static DP_55;//55 dp to px, do not count it each time, define it!
public static defineSize(Activity activity)
{
     DisplayMetrics metrics = new DisplayMetrics();
     activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
     DP_55 = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 55, metrics);
}

您的活动或片段:

public HashMap<String, SoftReference<Bitmap>> bitmaps = new HashMap<>();

从File 或Internet 加载图像为Bitmap,缩放到您的大小(55 dp)并放入字典:

if (!bitmaps.containsKey(urlOrPath)) {
     //Load 'bitmap' and put to dictionary:
     bitmaps.put(urlOrPath, new SoftReference<>(
                Bitmap.createScaledBitmap(
                        bitmap,
                        DisplayManager.DP_55, DisplayManager.DP_55, true)));
}
else //Just reuse it!
     iv_image.setImageBitmap(bitmaps.get(urlOrPath).get());

如何回收利用:

Iterator<Map.Entry<String, SoftReference<Bitmap>>> iterator = bitmaps.entrySet().iterator();
while (iterator.hasNext()) {
       iterator.next().getValue().get().recycle();
       iterator.remove();
}

您不会超出 40MB 的限制(如果 ImageView 大小很小并且有 否则使用 ImageLoaders(Glide、Picasso 等)。

【讨论】:

    猜你喜欢
    • 2011-03-01
    • 1970-01-01
    • 2012-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多