提高用户体验的安卓imageView图片加载方法

发布时间:2023-12-08

提高用户体验的安卓imageView图片加载方法

更新:<time datetime="2023-05-14 07:09">2023-05-14 07:09</time>

一、使用Glide库

在安卓开发中,图片加载是非常常见的需求,而使用Glide库可以轻松地实现高品质、流畅的图片加载,增强用户体验。 Glide库支持本地图片、网络图片、GIF图片等多种图片格式,同时还支持图像缩放、动画、转换等高级功能。 需要注意的是,在使用Glide库之前,需要先在build.gradle文件中添加Glide依赖:

dependencies {
    implementation 'com.github.bumptech.glide:glide:4.11.0'
    annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
}

接下来在代码中使用Glide加载图片:

Glide.with(this)
    .load("http://www.xxx.com/xxx.jpg")
    .placeholder(R.drawable.placeholder) // 占位图
    .error(R.drawable.error) // 错误图
    .into(imageView);

二、使用LruCache进行图片缓存

为了优化图片加载的性能,可以使用LruCache进行图片缓存,减少网络请求的次数。 LruCache是基于LRU(Least Recently Used)算法实现的一个缓存类,它可以按照缓存数据的使用频率来移除最近最少使用的数据对象。

// 初始化缓存
private LruCache<String, Bitmap> mMemoryCache;
private void initCache() {
    final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
    final int cacheSize = maxMemory / 8; // 1/8作为缓存大小
    mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
        @Override
        protected int sizeOf(String key, Bitmap bitmap) {
            return bitmap.getByteCount() / 1024;
        }
    };
}
// 存储缓存
private void addBitmapToMemoryCache(String key, Bitmap bitmap) {
    if (getBitmapFromMemoryCache(key) == null) {
        mMemoryCache.put(key, bitmap);
    }
}
// 读取缓存
private Bitmap getBitmapFromMemoryCache(String key) {
    return mMemoryCache.get(key);
}

使用缓存的方式:

Bitmap bitmap = getBitmapFromMemoryCache(url);
if (bitmap != null) {
    imageView.setImageBitmap(bitmap);
} else {
    Glide.with(MainActivity.this)
        .load(url)
        .placeholder(R.drawable.placeholder) // 占位图
        .error(R.drawable.error) // 错误图
        .listener(new RequestListener<Drawable>() {
            @Override
            public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
                return false;
            }
            @Override
            public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
                Bitmap bitmap = ((BitmapDrawable) resource).getBitmap();
                addBitmapToMemoryCache(url, bitmap); // 存储到缓存
                return false;
            }
        })
        .into(imageView);
}

三、使用RecyclerView进行图片列表展示

在实际开发中,经常需要实现图片列表的展示,而使用RecyclerView可以高效地展示大量图片,同时还可以实现下拉刷新、上拉加载等功能。 在RecyclerView中,可以使用GridLayoutManager来实现网格布局。 需要注意的是,在网格布局中,图片的宽度应该按比例调整,以避免图片变形。

RecyclerView recyclerView = findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new GridLayoutManager(this, 2)); // 网格布局,2列
recyclerView.setAdapter(new RecyclerView.Adapter<MyViewHolder>() {
    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(MainActivity.this).inflate(R.layout.item, parent, false);
        return new MyViewHolder(view);
    }
    @Override
    public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
        Glide.with(MainActivity.this)
            .load(urls[position % urls.length])
            .placeholder(R.drawable.placeholder) // 占位图
            .error(R.drawable.error) // 错误图
            .into(holder.imageView);
    }
    @Override
    public int getItemCount() {
        return 50;
    }
});
private static class MyViewHolder extends RecyclerView.ViewHolder {
    private ImageView imageView;
    MyViewHolder(View itemView) {
        super(itemView);
        imageView = itemView.findViewById(R.id.imageView);
        ViewGroup.LayoutParams lp = imageView.getLayoutParams();
        lp.width = getScreenWidth() / 2; // 调整宽度,保持比例
        lp.height = lp.width * 9 / 16;
        imageView.setLayoutParams(lp);
    }
}
private static int getScreenWidth() {
    WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
    Point point = new Point();
    windowManager.getDefaultDisplay().getSize(point);
    return point.x;
}