自定义了一个ImageView用于展示圆角图片:
public class RoundCornerImageView extends android.support.v7.widget.AppCompatImageView {
private int mRadius;
public RoundCornerImageView(Context context) {
super(context);
init(context, null);
}
public RoundCornerImageView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public RoundCornerImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}
private void init(Context context, AttributeSet attrs) {
if (attrs != null) {
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RoundCornerImageView);
try {
boolean hasRadius = typedArray.hasValue(R.styleable.RoundCornerImageView_roundcorner_radius);
if (hasRadius) {
int radius = typedArray.getInt(R.styleable.RoundCornerImageView_roundcorner_radius, 1);
mRadius = radius;
}
} finally {
typedArray.recycle();
}
}
}
public void setImage(String url) {
GlideRoundTransform glideRoundTransform;
if (mRadius == 0) {
glideRoundTransform = new GlideRoundTransform(getContext());
} else {
glideRoundTransform = new GlideRoundTransform(getContext(), mRadius);
}
Glide.with(TPApplication.getAppContext())
.load(url)
.centerCrop()
.transform(glideRoundTransform)
.placeholder(R.drawable.nearby_online_me_photo)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.dontAnimate()
.into(this);
}
}
其中,自定义了一个BitmapTransformation,用于实现圆角,代码为:
public class GlideRoundTransform extends BitmapTransformation {
private float mRadius = 0f;
public GlideRoundTransform(Context context) {
this(context, 4);
}
public GlideRoundTransform(Context context, int dp) {
super(context);
mRadius = DimentionUtil.dp2px(dp);
}
@Override
protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
return roundCrop(pool, toTransform);
}
@Override
public String getId() {
return getClass().getName() + Math.round(mRadius);
}
private Bitmap roundCrop(BitmapPool pool, Bitmap source) {
if (source == null) {
return null;
}
Bitmap result = pool.get(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888);
if (result == null) {
result = Bitmap.createBitmap(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888);
}
Canvas canvas = new Canvas(result);
Paint paint = new Paint();
paint.setShader(new BitmapShader(source, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));
paint.setAntiAlias(true);
RectF rectF = new RectF(0f, 0f, source.getWidth(), source.getHeight());
canvas.drawRoundRect(rectF, mRadius, mRadius, paint);
return result;
}
}
用这个自定义imageView展示图片是,xml代码为:
这样在java代码中:
private final RoundCornerImageView mAvatar;
mAvatar.setImage(url);
问题是,这样的结果是有些图片没有铺满整个view,说明.centerCrop()失效了。说明transform的设置覆盖了上一句.centerCrop()的作用。
于是我们就在xml中加了scaleType这个属性,即
运行结果显示:部分图片没有了圆角,倒是解决了没有铺满View的问题,但是铺满之后变成正方形了。说明transfom()没有生效。
分析发现,centerCorp的源码是:
public RequestOptions centerCrop() {
return transform(DownsampleStrategy.CENTER_OUTSIDE, new CenterCrop());
}
这样的意思就是:
这里面也是继承了BitmapTransformation这个类然后重画了一边,后面我们自己有调用了transform()这个方法等于把系统的Centercrop这个方法给覆盖了,所以说这两个属性谁在后面就用哪种效果。
于是就知道了:用自定义的BitmapTransformation将两个效果一起画出来!
public class GlideRoundTransform extends BitmapTransformation {
private float mRadius = 0f;
public GlideRoundTransform(Context context) {
this(context, 4);
}
public GlideRoundTransform(Context context, int dp) {
super(context);
mRadius = DimentionUtil.dp2px(dp);
}
@Override
protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
final Bitmap toReuse = pool.get(outWidth, outHeight, toTransform.getConfig() != null
? toTransform.getConfig() : Bitmap.Config.ARGB_8888);
Bitmap bitmap = TransformationUtils.centerCrop(toReuse, toTransform, outWidth, outHeight);
return roundCrop(pool, bitmap);
}
@Override
public String getId() {
return getClass().getName() + Math.round(mRadius);
}
private Bitmap roundCrop(BitmapPool pool, Bitmap source) {
if (source == null) {
return null;
}
Bitmap result = pool.get(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888);
if (result == null) {
result = Bitmap.createBitmap(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888);
}
Canvas canvas = new Canvas(result);
Paint paint = new Paint();
paint.setShader(new BitmapShader(source, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));
paint.setAntiAlias(true);
RectF rectF = new RectF(0f, 0f, source.getWidth(), source.getHeight());
canvas.drawRoundRect(rectF, mRadius, mRadius, paint);
return result;
}
}
这样的话,在自定义imageView是使用如下代码:
public void setImage(String url) {
GlideRoundTransform glideRoundTransform;
if (mRadius == 0) {
glideRoundTransform = new GlideRoundTransform(getContext());
} else {
glideRoundTransform = new GlideRoundTransform(getContext(), mRadius);
}
Glide.with(TPApplication.getAppContext())
.load(url)
.transform(glideRoundTransform)
.placeholder(R.drawable.nearby_online_me_photo)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.dontAnimate()
.into(this);
}
完美解决问题。