1. 程式人生 > >圓角ImageView的幾種實現方法

圓角ImageView的幾種實現方法

①自定義View

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.support.v7.widget.AppCompatImageView;
import android.util.AttributeSet;
import android.util.TypedValue;

/**
 * 自定義的圓角矩形ImageView,可以直接當元件在佈局中使用。
 */
public class RoundImageView extends AppCompatImageView{

    private Paint paint;
    private int pxRadius;

    public RoundImageView(Context context) {
        this(context,null);  
    }  

    public RoundImageView(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }  

    public RoundImageView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RoundImageView);
        float dpRadius = typedArray.getDimension(R.styleable.RoundImageView_radius, 0);
        pxRadius = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpRadius, context.getResources().getDisplayMetrics());
        typedArray.recycle();

        paint  = new Paint();
    }  

    /**
     * 繪製圓角矩形圖片
     */
    @Override  
    protected void onDraw(Canvas canvas) {
        Drawable drawable = getDrawable();  
        if (null != drawable) {  
            Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();  
            Bitmap b = getRoundBitmap(bitmap, pxRadius);
            final Rect rectSrc = new Rect(0, 0, b.getWidth(), b.getHeight());  
            final Rect rectDest = new Rect(0,0,getWidth(),getHeight());
            paint.reset();  
            canvas.drawBitmap(b, rectSrc, rectDest, paint);  

        } else {  
            super.onDraw(canvas);  
        }  
    }  

    /**
     * 獲取圓角矩形圖片方法
     * @param bitmap
     * @param roundPx,一般設定成14
     * @return Bitmap
     */
    private Bitmap getRoundBitmap(Bitmap bitmap, int roundPx) {  
        Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),  
                bitmap.getHeight(), Config.ARGB_8888);  
        Canvas canvas = new Canvas(output);  

        final int color = 0xff424242;

        final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());  
        final RectF rectF = new RectF(rect);
        paint.setAntiAlias(true);  
        canvas.drawARGB(0, 0, 0, 0);  
        paint.setColor(color);  
        int x = bitmap.getWidth(); 

        canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
        paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));  
        canvas.drawBitmap(bitmap, rect, rect, paint);  
        return output;
    }  
}

②使用Glide等第三方框架:

private RequestOptions requestOptions = RequestOptions.circleCropTransform();

...

Glide.with(mContext).load(R.mipmap.dialer_dial).apply(requestOptions).into(mContactHolder.civ_contact);

③Glide實現方法二

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Shader;
import android.support.annotation.NonNull;
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
import com.bumptech.glide.load.resource.bitmap.BitmapTransformation;

import java.security.MessageDigest;

public class RoundedCornersTransformation extends BitmapTransformation {

  private static final int VERSION = 1;
  private static final String ID = "jp.wasabeef.glide.transformations.RoundedCornersTransformation." + VERSION;

  public enum CornerType {
    ALL,
    TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT,
    TOP, BOTTOM, LEFT, RIGHT,
    OTHER_TOP_LEFT, OTHER_TOP_RIGHT, OTHER_BOTTOM_LEFT, OTHER_BOTTOM_RIGHT,
    DIAGONAL_FROM_TOP_LEFT, DIAGONAL_FROM_TOP_RIGHT
  }

  private int radius;
  private int diameter;
  private int margin;
  private CornerType cornerType;

  public RoundedCornersTransformation(int radius, int margin) {
    this(radius, margin, CornerType.ALL);
  }

  public RoundedCornersTransformation(int radius, int margin, CornerType cornerType) {
    this.radius = radius;
    this.diameter = this.radius * 2;
    this.margin = margin;
    this.cornerType = cornerType;
  }

  @Override protected Bitmap transform(@NonNull BitmapPool pool,
      @NonNull Bitmap toTransform, int outWidth, int outHeight) {
    int width = toTransform.getWidth();
    int height = toTransform.getHeight();

    Bitmap bitmap = pool.get(width, height, Bitmap.Config.ARGB_8888);
    bitmap.setHasAlpha(true);

    Canvas canvas = new Canvas(bitmap);
    Paint paint = new Paint();
    paint.setAntiAlias(true);
    paint.setShader(new BitmapShader(toTransform, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));
    drawRoundRect(canvas, paint, width, height);
    return bitmap;
  }

  private void drawRoundRect(Canvas canvas, Paint paint, float width, float height) {
    float right = width - margin;
    float bottom = height - margin;

    switch (cornerType) {
      case ALL:
        canvas.drawRoundRect(new RectF(margin, margin, right, bottom), radius, radius, paint);
        break;
      case TOP_LEFT:
        drawTopLeftRoundRect(canvas, paint, right, bottom);
        break;
      case TOP_RIGHT:
        drawTopRightRoundRect(canvas, paint, right, bottom);
        break;
      case BOTTOM_LEFT:
        drawBottomLeftRoundRect(canvas, paint, right, bottom);
        break;
      case BOTTOM_RIGHT:
        drawBottomRightRoundRect(canvas, paint, right, bottom);
        break;
      case TOP:
        drawTopRoundRect(canvas, paint, right, bottom);
        break;
      case BOTTOM:
        drawBottomRoundRect(canvas, paint, right, bottom);
        break;
      case LEFT:
        drawLeftRoundRect(canvas, paint, right, bottom);
        break;
      case RIGHT:
        drawRightRoundRect(canvas, paint, right, bottom);
        break;
      case OTHER_TOP_LEFT:
        drawOtherTopLeftRoundRect(canvas, paint, right, bottom);
        break;
      case OTHER_TOP_RIGHT:
        drawOtherTopRightRoundRect(canvas, paint, right, bottom);
        break;
      case OTHER_BOTTOM_LEFT:
        drawOtherBottomLeftRoundRect(canvas, paint, right, bottom);
        break;
      case OTHER_BOTTOM_RIGHT:
        drawOtherBottomRightRoundRect(canvas, paint, right, bottom);
        break;
      case DIAGONAL_FROM_TOP_LEFT:
        drawDiagonalFromTopLeftRoundRect(canvas, paint, right, bottom);
        break;
      case DIAGONAL_FROM_TOP_RIGHT:
        drawDiagonalFromTopRightRoundRect(canvas, paint, right, bottom);
        break;
      default:
        canvas.drawRoundRect(new RectF(margin, margin, right, bottom), radius, radius, paint);
        break;
    }
  }

  private void drawTopLeftRoundRect(Canvas canvas, Paint paint, float right, float bottom) {
    canvas.drawRoundRect(new RectF(margin, margin, margin + diameter, margin + diameter), radius,
        radius, paint);
    canvas.drawRect(new RectF(margin, margin + radius, margin + radius, bottom), paint);
    canvas.drawRect(new RectF(margin + radius, margin, right, bottom), paint);
  }

  private void drawTopRightRoundRect(Canvas canvas, Paint paint, float right, float bottom) {
    canvas.drawRoundRect(new RectF(right - diameter, margin, right, margin + diameter), radius,
        radius, paint);
    canvas.drawRect(new RectF(margin, margin, right - radius, bottom), paint);
    canvas.drawRect(new RectF(right - radius, margin + radius, right, bottom), paint);
  }

  private void drawBottomLeftRoundRect(Canvas canvas, Paint paint, float right, float bottom) {
    canvas.drawRoundRect(new RectF(margin, bottom - diameter, margin + diameter, bottom), radius,
        radius, paint);
    canvas.drawRect(new RectF(margin, margin, margin + diameter, bottom - radius), paint);
    canvas.drawRect(new RectF(margin + radius, margin, right, bottom), paint);
  }

  private void drawBottomRightRoundRect(Canvas canvas, Paint paint, float right, float bottom) {
    canvas.drawRoundRect(new RectF(right - diameter, bottom - diameter, right, bottom), radius,
        radius, paint);
    canvas.drawRect(new RectF(margin, margin, right - radius, bottom), paint);
    canvas.drawRect(new RectF(right - radius, margin, right, bottom - radius), paint);
  }

  private void drawTopRoundRect(Canvas canvas, Paint paint, float right, float bottom) {
    canvas.drawRoundRect(new RectF(margin, margin, right, margin + diameter), radius, radius,
        paint);
    canvas.drawRect(new RectF(margin, margin + radius, right, bottom), paint);
  }

  private void drawBottomRoundRect(Canvas canvas, Paint paint, float right, float bottom) {
    canvas.drawRoundRect(new RectF(margin, bottom - diameter, right, bottom), radius, radius,
        paint);
    canvas.drawRect(new RectF(margin, margin, right, bottom - radius), paint);
  }

  private void drawLeftRoundRect(Canvas canvas, Paint paint, float right, float bottom) {
    canvas.drawRoundRect(new RectF(margin, margin, margin + diameter, bottom), radius, radius,
        paint);
    canvas.drawRect(new RectF(margin + radius, margin, right, bottom), paint);
  }

  private void drawRightRoundRect(Canvas canvas, Paint paint, float right, float bottom) {
    canvas.drawRoundRect(new RectF(right - diameter, margin, right, bottom), radius, radius, paint);
    canvas.drawRect(new RectF(margin, margin, right - radius, bottom), paint);
  }

  private void drawOtherTopLeftRoundRect(Canvas canvas, Paint paint, float right, float bottom) {
    canvas.drawRoundRect(new RectF(margin, bottom - diameter, right, bottom), radius, radius,
        paint);
    canvas.drawRoundRect(new RectF(right - diameter, margin, right, bottom), radius, radius, paint);
    canvas.drawRect(new RectF(margin, margin, right - radius, bottom - radius), paint);
  }

  private void drawOtherTopRightRoundRect(Canvas canvas, Paint paint, float right, float bottom) {
    canvas.drawRoundRect(new RectF(margin, margin, margin + diameter, bottom), radius, radius,
        paint);
    canvas.drawRoundRect(new RectF(margin, bottom - diameter, right, bottom), radius, radius,
        paint);
    canvas.drawRect(new RectF(margin + radius, margin, right, bottom - radius), paint);
  }

  private void drawOtherBottomLeftRoundRect(Canvas canvas, Paint paint, float right, float bottom) {
    canvas.drawRoundRect(new RectF(margin, margin, right, margin + diameter), radius, radius,
        paint);
    canvas.drawRoundRect(new RectF(right - diameter, margin, right, bottom), radius, radius, paint);
    canvas.drawRect(new RectF(margin, margin + radius, right - radius, bottom), paint);
  }

  private void drawOtherBottomRightRoundRect(Canvas canvas, Paint paint, float right,
      float bottom) {
    canvas.drawRoundRect(new RectF(margin, margin, right, margin + diameter), radius, radius,
        paint);
    canvas.drawRoundRect(new RectF(margin, margin, margin + diameter, bottom), radius, radius,
        paint);
    canvas.drawRect(new RectF(margin + radius, margin + radius, right, bottom), paint);
  }

  private void drawDiagonalFromTopLeftRoundRect(Canvas canvas, Paint paint, float right,
      float bottom) {
    canvas.drawRoundRect(new RectF(margin, margin, margin + diameter, margin + diameter), radius,
        radius, paint);
    canvas.drawRoundRect(new RectF(right - diameter, bottom - diameter, right, bottom), radius,
        radius, paint);
    canvas.drawRect(new RectF(margin, margin + radius, right - diameter, bottom), paint);
    canvas.drawRect(new RectF(margin + diameter, margin, right, bottom - radius), paint);
  }

  private void drawDiagonalFromTopRightRoundRect(Canvas canvas, Paint paint, float right,
      float bottom) {
    canvas.drawRoundRect(new RectF(right - diameter, margin, right, margin + diameter), radius,
        radius, paint);
    canvas.drawRoundRect(new RectF(margin, bottom - diameter, margin + diameter, bottom), radius,
        radius, paint);
    canvas.drawRect(new RectF(margin, margin, right - radius, bottom - radius), paint);
    canvas.drawRect(new RectF(margin + radius, margin + radius, right, bottom), paint);
  }

  @Override public String toString() {
    return "RoundedTransformation(radius=" + radius + ", margin=" + margin + ", diameter="
        + diameter + ", cornerType=" + cornerType.name() + ")";
  }

  @Override public boolean equals(Object o) {
    return o instanceof RoundedCornersTransformation &&
        ((RoundedCornersTransformation) o).radius == radius &&
        ((RoundedCornersTransformation) o).diameter == diameter &&
        ((RoundedCornersTransformation) o).margin == margin &&
        ((RoundedCornersTransformation) o).cornerType == cornerType;
  }

  @Override public int hashCode() {
    return ID.hashCode() + radius * 10000 + diameter * 1000 + margin * 100 + cornerType.ordinal() * 10;
  }

  @Override public void updateDiskCacheKey(@NonNull MessageDigest messageDigest) {
    messageDigest.update((ID + radius + diameter + margin + cornerType).getBytes(CHARSET));
  }
}
Glide.with(mContext).load(mResId[position]).apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(50, 0))).into(holder.mImageView);