如何自定义ImageView使其默认通过Glide加载图片?
当然可行!这种方案完全没问题
自定义ImageView来默认用Glide加载图片是个很棒的想法——既能统一项目里的图片加载逻辑,又能直接复用Glide的内存优化、缓存策略、图片压缩等能力,不用每次都重复写Glide的加载代码。下面一步步教你实现:
1. 完善自定义View的构造方法
首先要补全ImageView的三个构造方法,因为XML初始化会用到带AttributeSet的构造,我们需要在这里处理XML里的图片属性:
public class GlideImageView extends ImageView { public GlideImageView(Context context) { super(context); } public GlideImageView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); // 处理XML中设置的图片属性 parseXmlAttributes(attrs); } public GlideImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); parseXmlAttributes(attrs); } }
2. 拦截XML中的图片属性
在parseXmlAttributes方法里,我们读取XML里的android:src和android:background属性,把它们交给Glide加载:
private void parseXmlAttributes(AttributeSet attrs) { if (attrs == null) return; // 获取XML中设置的android:src资源ID int srcResId = attrs.getAttributeResourceValue("http://schemas.android.com/apk/res/android", "src", -1); if (srcResId != -1) { setImageResource(srcResId); } // 获取XML中设置的android:background资源ID int bgResId = attrs.getAttributeResourceValue("http://schemas.android.com/apk/res/android", "background", -1); if (bgResId != -1) { setBackgroundResource(bgResId); } }
3. 重写原生图片设置方法,替换为Glide逻辑
接下来重写ImageView所有设置图片的入口方法,让它们内部用Glide加载,不管是Java代码调用还是XML初始化都会生效:
处理src属性(图片内容)
@Override public void setImageResource(int resId) { // 用Glide加载资源到ImageView的src Glide.with(this) .load(resId) // 可以添加默认的占位图、错误图,根据需求调整 .placeholder(R.drawable.default_placeholder) .error(R.drawable.default_error) .into(this); } @Override public void setImageURI(@Nullable Uri uri) { if (uri == null) return; Glide.with(this) .load(uri) .placeholder(R.drawable.default_placeholder) .error(R.drawable.default_error) .into(this); }
处理background属性(背景图)
背景图需要用CustomTarget来获取Drawable,因为Glide的into(this)是针对ImageView的src的:
@Override public void setBackgroundResource(int resId) { Glide.with(this) .load(resId) .placeholder(R.drawable.default_bg_placeholder) .error(R.drawable.default_bg_error) .into(new CustomTarget<Drawable>() { @Override public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) { setBackground(resource); } @Override public void onLoadCleared(@Nullable Drawable placeholder) { setBackground(placeholder); } }); }
4. 额外扩展:支持网络图片加载
如果需要加载网络图片,可以给自定义View加一个专门的方法:
public void loadNetworkImage(String imageUrl) { Glide.with(this) .load(imageUrl) .placeholder(R.drawable.default_placeholder) .error(R.drawable.default_error) // 可选:添加图片变换,比如圆角、裁剪 .centerCrop() .into(this); }
注意事项
- 确保你的项目已经添加了Glide依赖(最新版本可以根据官方文档调整):
implementation 'com.github.bumptech.glide:glide:4.16.0' annotationProcessor 'com.github.bumptech.glide:compiler:4.16.0' - Glide的生命周期绑定:
Glide.with(this)会自动绑定当前View的生命周期,避免内存泄漏 - 如果加载网络图片,别忘了在Manifest里添加网络权限:
<uses-permission android:name="android.permission.INTERNET" />
这样一来,不管你是在XML里写app:srcCompat="@drawable/xxx"、android:background="@drawable/xxx",还是在Java代码里调用setImageResource、loadNetworkImage,都会通过Glide加载图片,自动享受Glide的性能优化~
内容的提问来源于stack exchange,提问作者Jawad Zeb
相关产品推荐
相关产品推荐

