自定義ImageView實現圓角
阿新 • • 發佈:2019-01-02
package com.electric.view;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.widget.ImageView;
import com.electric.R;
public class RoundImageView extends ImageView{
/** 圖片的型別,圓形或者圓角 **/ private int type; private static final int TYPE_CIRCLE = 0; private static final int TYPE_ROUND = 1; /** 圓角的預設值 **/ private static final int BODER_RADIUS_DEFAULT = 10; private int mBorderRadius; private Paint mBitmapPaint; /** 圓角的半徑 **/ private int mRadius; private Matrix mMatrix; private BitmapShader mBitmapShader; private int mWidth; private RectF mRoundRect; public RoundImageView(Context context) { super(context); init(context, null); } public RoundImageView(Context context, AttributeSet attrs) { super(context, attrs); init(context, attrs); } private void init(Context context, AttributeSet attrs){ mMatrix = new Matrix(); mBitmapPaint = new Paint(); mBitmapPaint.setAntiAlias(true); TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RoundImageView); mBorderRadius = a.getDimensionPixelSize( R.styleable.RoundImageView_borderRadius, (int) TypedValue .applyDimension(TypedValue.COMPLEX_UNIT_DIP, BODER_RADIUS_DEFAULT, getResources() .getDisplayMetrics())); type = a.getInt(R.styleable.RoundImageView_type, TYPE_CIRCLE);// 預設為Circle a.recycle(); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); // 圓角圖片的範圍 if (type == TYPE_ROUND) mRoundRect = new RectF(0, 0, getWidth(), getHeight()); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); if (type == TYPE_CIRCLE) { mWidth = Math.min(getMeasuredWidth(), getMeasuredHeight()); mRadius = mWidth / 2; setMeasuredDimension(mWidth, mWidth); } } @Override protected void onDraw(Canvas canvas) { if (getDrawable() == null) { return; } setUpShader(); if (type == TYPE_ROUND) { canvas.drawRoundRect(mRoundRect, mBorderRadius, mBorderRadius, mBitmapPaint); } else { canvas.drawCircle(mRadius, mRadius, mRadius, mBitmapPaint); } } private void setUpShader() { Drawable drawable = getDrawable(); if (drawable == null) { return; } Bitmap bmp = drawableToBitamp(drawable); // 將bmp作為著色器,就是在指定區域內繪製bmp mBitmapShader = new BitmapShader(bmp, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); float scale = 1.0f; if (type == TYPE_CIRCLE) { // 拿到bitmap寬或高的小值 int bSize = Math.min(bmp.getWidth(), bmp.getHeight()); scale = mWidth * 1.0f / bSize; } else if (type == TYPE_ROUND) { // 如果圖片的寬或者高與view的寬高不匹配,計算出需要縮放的比例;縮放後的圖片的寬高, 一定要大於我們view的寬高;所以我們這裡取大值; scale = Math.max(getWidth() * 1.0f / bmp.getWidth(), getHeight() * 1.0f / bmp.getHeight()); } // shader的變換矩陣,我們這裡主要用於放大或者縮小 mMatrix.setScale(scale, scale); // 設定變換矩陣 mBitmapShader.setLocalMatrix(mMatrix); // 設定shader mBitmapPaint.setShader(mBitmapShader); } /** * drawable轉bitmap * * @param drawable * @return */ private Bitmap drawableToBitamp(Drawable drawable) { if (drawable instanceof BitmapDrawable) { BitmapDrawable bd = (BitmapDrawable) drawable; return bd.getBitmap(); } int w = drawable.getIntrinsicWidth(); int h = drawable.getIntrinsicHeight(); Bitmap bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); drawable.setBounds(0, 0, w, h); drawable.draw(canvas); return bitmap; }
}