ImageLoader自带圆角图片的RoundedBitmapDisplayer,但这个displayer展示的效果是4个角都是圆角,而我们有时候只需要其中的上面或下面2个角是圆角,本篇就是讲这个方法的。
package com.uil;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.drawable.Drawable;
import com.nostra13.universalimageloader.core.assist.LoadedFrom;
import com.nostra13.universalimageloader.core.display.BitmapDisplayer;
import com.nostra13.universalimageloader.core.imageaware.ImageAware;
import com.nostra13.universalimageloader.core.imageaware.ImageViewAware;
/**
* Created by zhu.jiangtao on 2017/11/30.
*/
public class CornorBitmapDisplayer implements BitmapDisplayer {
private int mTopLeftRadius;
private int mTopRightRadius;
private int mBottomRightRadius;
private int mBottomLeftRadius;
private int mMarginPixels;
public CornorBitmapDisplayer(int topLeftRadius, int topRightRadius, int bottomRightRadius, int bottomLeftRadius) {
this(topLeftRadius, topRightRadius, bottomRightRadius, bottomLeftRadius, 0);
}
public CornorBitmapDisplayer(int topLeftRadius, int topRightRadius, int bottomRightRadius, int bottomLeftRadius, int marginPixels) {
this.mTopLeftRadius = topLeftRadius;
this.mTopRightRadius = topRightRadius;
this.mBottomRightRadius = bottomRightRadius;
this.mBottomLeftRadius = bottomLeftRadius;
this.mMarginPixels = marginPixels;
}
public void display(Bitmap bitmap, ImageAware imageAware, LoadedFrom loadedFrom) {
if(!(imageAware instanceof ImageViewAware)) {
throw new IllegalArgumentException("ImageAware should wrap ImageView. ImageViewAware is expected.");
} else {
imageAware.setImageDrawable(new CornorBitmapDisplayer.CornerDrawable(bitmap, this.mTopLeftRadius, this.mTopRightRadius, this.mBottomRightRadius, this.mBottomLeftRadius, this.mMarginPixels));
}
}
protected static class CornerDrawable extends Drawable {
private int mTopLeftRadius;
private int mTopRightRadius;
private int mBottomRightRadius;
private int mBottomLeftRadius;
private int mMargin;
private final RectF mRect = new RectF();
private final BitmapShader bitmapShader;
private final Paint paint;
private final RectF mBmpRect;
public CornerDrawable(Bitmap bitmap, int topLeftRadius, int topRightRadius, int bottomRightRadius, int bottomLeftRadius, int marginPixels) {
this.mTopLeftRadius = topLeftRadius;
this.mTopRightRadius = topRightRadius;
this.mBottomRightRadius = bottomRightRadius;
this.mBottomLeftRadius = bottomLeftRadius;
this.mMargin = marginPixels;
this.bitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
this.mBmpRect = new RectF((float)this.mMargin, (float)this.mMargin, (float)(bitmap.getWidth() - this.mMargin), (float)(bitmap.getHeight() - this.mMargin));
this.paint = new Paint();
this.paint.setAntiAlias(true);
this.paint.setShader(this.bitmapShader);
}
protected void onBoundsChange(Rect bounds) {
super.onBoundsChange(bounds);
this.mRect.set((float)this.mMargin, (float)this.mMargin, (float)(bounds.width() - this.mMargin), (float)(bounds.height() - this.mMargin));
Matrix mResizeMatrix = new Matrix();
mResizeMatrix.setRectToRect(this.mBmpRect, this.mRect, Matrix.ScaleToFit.FILL);
this.bitmapShader.setLocalMatrix(mResizeMatrix);
}
public void draw(Canvas canvas) {
float[] radii = new float[]{(float)this.mTopLeftRadius, (float)this.mTopLeftRadius, (float)this.mTopRightRadius, (float)this.mTopRightRadius, (float)this.mBottomRightRadius, (float)this.mBottomRightRadius, (float)this.mBottomLeftRadius, (float)this.mBottomLeftRadius};
Path path = new Path();
path.addRoundRect(this.mRect, radii, Path.Direction.CW);
canvas.drawPath(path, this.paint);
}
public int getOpacity() {
return PixelFormat.TRANSLUCENT;
}
public void setAlpha(int alpha) {
this.paint.setAlpha(alpha);
}
public void setColorFilter(ColorFilter cf) {
this.paint.setColorFilter(cf);
}
}
}
绝大部分代码都和RoundedBitmapDisplayer是一样的,只是onDraw中的利用path绘制圆角矩形的方法有点区别而已。
我们把这段代码单独拿出来看:
public void draw(Canvas canvas) {
float[] radii = new float[]{(float)this.mTopLeftRadius, (float)this.mTopLeftRadius, (float)this.mTopRightRadius, (float)this.mTopRightRadius, (float)this.mBottomRightRadius, (float)this.mBottomRightRadius, (float)this.mBottomLeftRadius, (float)this.mBottomLeftRadius};
Path path = new Path();
path.addRoundRect(this.mRect, radii, Path.Direction.CW);
canvas.drawPath(path, this.paint);
}
主要调用的是 Path的addRoundRect(RectF rect, float[] radii, Direction dir)方法。radii中的值分别表示 左上、右上、左下和右下圆角的X,Y值。
而RoundedBitmapDisplayer中的onDraw方法却是4个角都是圆角:
public void draw(Canvas canvas) {
canvas.drawRoundRect(mRect, cornerRadius, cornerRadius, paint);
}
调用的Path的 drawRoundRect(@NonNull RectF rect, float rx, float ry, @NonNull Paint paint) 即将rect的四个角都画为圆角。
用的方法也很简单,
//显示图片的配置
DisplayImageOptions options = new DisplayImageOptions.Builder()
.showImageOnLoading(R.drawable.ic_stub)
.showImageOnFail(R.drawable.ic_error)
.showImageForEmptyUri(R.drawable.ic_empty)
.cacheInMemory(true)
.cacheOnDisk(true)
.bitmapConfig(Bitmap.Config.RGB_565)
.displayer(new CornorBitmapDisplayer(20, 20, 0, 0))//左上、和右上为圆角
.build();
ImageLoader.getInstance().displayImage(url, imgview, options, null);
效果如下:
注意:显示图片的ImageView需要设置具体的大小而不能是wrap_content