绘制流程:
1.根据获取的属性值,判断显示模式,并设置圆形图片、外边框、内边框的半径值
2.画边框
3.画图片内容
(1)获取原图
(2)得到正方形图
(3)得到缩放图
(4)得到圆形图
public class MyRoundImageView extends ImageView { private int defaultColor = 0xffffffff; private ShowType mShowType = ShowType.NoBorder; private int mBorderThickness = 0; private int mBorderInsideColor; private int mBorderOutsideColor; private int mRadius = 0; enum ShowType {InsideBorder,OutsideBorder,InsideAndOutsideBorder,NoBorder} public MyRoundImageView(Context context) {super(context);} public MyRoundImageView(Context context, AttributeSet attrs) {super(context, attrs);readAttrs(attrs);} public MyRoundImageView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);readAttrs(attrs);} private void readAttrs(AttributeSet attrs) { TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.RoundImageView);mBorderThickness = a.getDimensionPixelSize(R.styleable.RoundImageView_border_thickness, 0);mBorderInsideColor = a.getColor(R.styleable.RoundImageView_border_inside_color, defaultColor);mBorderOutsideColor = a.getColor(R.styleable.RoundImageView_border_outside_color, defaultColor);readShowType();} private void readShowType() {if (mBorderInsideColor != defaultColor && mBorderOutsideColor != defaultColor) {mShowType = ShowType.InsideAndOutsideBorder;} else if (mBorderInsideColor != defaultColor && mBorderOutsideColor == defaultColor) {mShowType = ShowType.InsideBorder;} else if (mBorderInsideColor == defaultColor && mBorderOutsideColor != defaultColor) {mShowType = ShowType.OutsideBorder;} else {mShowType = ShowType.NoBorder;} } @Overrideprotected void onDraw(Canvas canvas) {switch (mShowType) {case InsideBorder:mRadius = (getWidth() < getHeight() ? getWidth() : getHeight()) / 2 - mBorderThickness;drawRoundBorder(canvas, mRadius + mBorderThickness / 2, mBorderInsideColor); break; case OutsideBorder:mRadius = (getWidth() < getHeight() ? getWidth() : getHeight()) / 2 - mBorderThickness;drawRoundBorder(canvas, mRadius + mBorderThickness / 2, mBorderOutsideColor); break; case InsideAndOutsideBorder:mRadius = (getWidth() < getHeight() ? getWidth() : getHeight()) / 2 - mBorderThickness * 2;drawRoundBorder(canvas, mRadius + mBorderThickness / 2, mBorderInsideColor);drawRoundBorder(canvas, mRadius + mBorderThickness / 2 + mBorderThickness, mBorderOutsideColor); break; case NoBorder:mRadius = (getWidth() < getHeight() ? getWidth() : getHeight()) / 2; break; default: } drawBitmapContent(canvas);} private void drawRoundBorder(Canvas canvas, int radius, int color) { Paint paint = new Paint();paint.setAntiAlias(true);paint.setFilterBitmap(true);paint.setDither(true);paint.setColor(color);paint.setStyle(Paint.Style.STROKE);paint.setStrokeWidth(mBorderThickness);canvas.drawCircle(getWidth() / 2, getHeight() / 2, radius, paint);} private void drawBitmapContent(Canvas canvas) { canvas.drawBitmap(bitmapToRound(bitmapToScale(bitmapToSquare(readBitmap()))), getWidth() / 2 - mRadius, getHeight() / 2 - mRadius, null);} private Bitmap readBitmap() { Drawable drawable = getDrawable(); if (drawable == null) {return null;}if (drawable instanceof NinePatchDrawable) {return null;}if (drawable instanceof BitmapDrawable) {return ((BitmapDrawable) drawable).getBitmap().copy(Bitmap.Config.ARGB_8888, true);}return null;} private Bitmap bitmapToSquare(Bitmap bitmap) {int w = bitmap.getWidth(); int h = bitmap.getHeight(); int x = w > h ? (w - h) / 2 : 0; int y = w > h ? 0 : (h - w) / 2; int sideLength = w > h ? h : w; return Bitmap.createBitmap(bitmap, 0, 0, sideLength, sideLength);} private Bitmap bitmapToScale(Bitmap bitmap) {return Bitmap.createScaledBitmap(bitmap, mRadius * 2,mRadius * 2, true);} public Bitmap bitmapToRound(Bitmap bitmap) { Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),bitmap.getHeight(), Bitmap.Config.ARGB_8888);Canvas canvas = new Canvas(output);Paint paint = new Paint();Rect rect = new Rect(0, 0, output.getWidth(),output.getHeight());paint.setAntiAlias(true);canvas.drawRoundRect(new RectF(rect), rect.width()/2, rect.height()/2, paint);//取output的图层与bitmap的图层的交集paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));//参数2是截取原图区域,可以不是全部图片,参数3是显示位置区域canvas.drawBitmap(bitmap, rect, rect, paint); return output;} }
附1.设置两张图片相交时的模式
/** * setXfermode 设置两张图片相交时的模式*/// PorterDuff.Mode.CLEAR 清除画布上图像// PorterDuff.Mode.SRC 显示上层图像// PorterDuff.Mode.DST 显示下层图像// PorterDuff.Mode.SRC_OVER上下层图像都显示,上层居上显示// PorterDuff.Mode.DST_OVER 上下层都显示,下层居上显示// PorterDuff.Mode.SRC_IN 取两层图像交集部门,只显示上层图像// PorterDuff.Mode.DST_IN 取两层图像交集部门,只显示下层图像// PorterDuff.Mode.SRC_OUT 取上层图像非交集部门// PorterDuff.Mode.DST_OUT 取下层图像非交集部门// PorterDuff.Mode.SRC_ATOP 取下层图像非交集部门与上层图像交集部门// PorterDuff.Mode.DST_ATOP 取上层图像非交集部门与下层图像交集部门// PorterDuff.Mode.XOR 取两层图像的非交集部门
参考资料:
http://blog.csdn.net/alan_biao/article/details/17379925
时间: 2024-10-10 11:02:02