ImageLoader中自定义Displayer来展示任意圆角

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zhujiangtaotaise/article/details/78679909

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

猜你喜欢

转载自blog.csdn.net/zhujiangtaotaise/article/details/78679909