600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > 自定义圆角圆形图片

自定义圆角圆形图片

时间:2019-05-05 23:23:46

相关推荐

自定义圆角圆形图片

第一种自定义控件NiceImageView

public class NiceImageView extends AppCompatImageView {/*** 图片的类型,圆形or圆角*/private int type;public static final int TYPE_CIRCLE = 0;public static final int TYPE_ROUND = 1;public static final int TYPE_OVAL = 2;/*** 描边的颜色、宽度*/private int mBorderColor;private float mBorderWidth;/*** 圆角的大小*/private float mCornerRadius;//左上角圆角大小private float mLeftTopCornerRadius;//右上角圆角大小private float mRightTopCornerRadius;//左下角圆角大小private float mLeftBottomCornerRadius;//右下角圆角大小private float mRightBottomCornerRadius;/*** 绘图的Paint*/private Paint mBitmapPaint;private Paint mBorderPaint;/*** 圆角的半径*/private float mRadius;/*** 3x3 矩阵,主要用于缩小放大*/private Matrix mMatrix;/*** 渲染图像,使用图像为绘制图形着色*/private BitmapShader mBitmapShader;/*** view的宽度*/private int mWidth;/*** 圆角图片区域*/private RectF mRoundRect;private Path mRoundPath;public NiceImageView(Context context) {this(context, null);}public NiceImageView(Context context, AttributeSet attrs) {this(context, attrs, 0);}public NiceImageView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.NiceImageView, defStyleAttr, 0);type = a.getInt(R.styleable.NiceImageView_type, TYPE_OVAL);mBorderColor = a.getColor(R.styleable.NiceImageView_border_color, Color.TRANSPARENT);mBorderWidth = a.getDimension(R.styleable.NiceImageView_border_width, 0);mCornerRadius = a.getDimension(R.styleable.NiceImageView_corner_radius, dp2px(10));mLeftTopCornerRadius = a.getDimension(R.styleable.NiceImageView_leftTop_corner_radius, 0);mLeftBottomCornerRadius = a.getDimension(R.styleable.NiceImageView_leftBottom_corner_radius, 0);mRightTopCornerRadius = a.getDimension(R.styleable.NiceImageView_rightTop_corner_radius, 0);mRightBottomCornerRadius = a.getDimension(R.styleable.NiceImageView_rightBottom_corner_radius, 0);a.recycle();init();}private void init() {mRoundPath = new Path();mMatrix = new Matrix();mBitmapPaint = new Paint();mBitmapPaint.setAntiAlias(true);mBorderPaint = new Paint();mBorderPaint.setAntiAlias(true);mBorderPaint.setStyle(Paint.Style.STROKE);}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);/*** 如果类型是圆形,则强制改变view的宽高一致,以小值为准*/if (type == TYPE_CIRCLE) {mWidth = Math.min(MeasureSpec.getSize(widthMeasureSpec),MeasureSpec.getSize(heightMeasureSpec));mRadius = mWidth / 2 - mBorderWidth / 2;setMeasuredDimension(mWidth, mWidth);}}@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {super.onSizeChanged(w, h, oldw, oldh);// 圆角图片的范围if (type == TYPE_ROUND || type == TYPE_OVAL) {mRoundRect = new RectF(mBorderWidth / 2, mBorderWidth / 2, w - mBorderWidth / 2, h - mBorderWidth / 2);}}@Overrideprotected void onDraw(Canvas canvas) {mBorderPaint.setColor(mBorderColor);mBorderPaint.setStrokeWidth(mBorderWidth);if (getDrawable() == null) {return;}setUpShader();if (type == TYPE_ROUND) {setRoundPath();canvas.drawPath(mRoundPath, mBitmapPaint);//绘制描边canvas.drawPath(mRoundPath, mBorderPaint);} else if (type == TYPE_CIRCLE) {canvas.drawCircle(mRadius + mBorderWidth / 2, mRadius + mBorderWidth / 2, mRadius, mBitmapPaint);//绘制描边canvas.drawCircle(mRadius + mBorderWidth / 2, mRadius + mBorderWidth / 2, mRadius, mBorderPaint);} else {canvas.drawOval(mRoundRect, mBitmapPaint);canvas.drawOval(mRoundRect, mBorderPaint);}}private void setRoundPath() {mRoundPath.reset();/*** 如果四个圆角大小都是默认值0,* 则将四个圆角大小设置为mCornerRadius的值*/if (mLeftTopCornerRadius == 0 &&mLeftBottomCornerRadius == 0 &&mRightTopCornerRadius == 0 &&mRightBottomCornerRadius == 0) {mRoundPath.addRoundRect(mRoundRect,new float[]{mCornerRadius, mCornerRadius,mCornerRadius, mCornerRadius,mCornerRadius, mCornerRadius,mCornerRadius, mCornerRadius},Path.Direction.CW);} else {mRoundPath.addRoundRect(mRoundRect,new float[]{mLeftTopCornerRadius, mLeftTopCornerRadius,mRightTopCornerRadius, mRightTopCornerRadius,mRightBottomCornerRadius, mRightBottomCornerRadius,mLeftBottomCornerRadius, mLeftBottomCornerRadius},Path.Direction.CW);}}/*** 初始化BitmapShader*/private void setUpShader() {Drawable drawable = getDrawable();if (drawable == null) {return;}Bitmap bmp = drawableToBitamp(drawable);// 将bmp作为着色器,就是在指定区域内绘制bmpmBitmapShader = 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;//使缩放后的图片居中float dx = (bmp.getWidth() * scale - mWidth) / 2;float dy = (bmp.getHeight() * scale - mWidth) / 2;mMatrix.setTranslate(-dx, -dy);} else if (type == TYPE_ROUND || type == TYPE_OVAL) {if (!(bmp.getWidth() == getWidth() && bmp.getHeight() == getHeight())) {// 如果图片的宽或者高与view的宽高不匹配,计算出需要缩放的比例;缩放后的图片的宽高,一定要大于我们view的宽高;所以我们这里取大值;scale = Math.max(getWidth() * 1.0f / bmp.getWidth(),getHeight() * 1.0f / bmp.getHeight());//使缩放后的图片居中float dx = (scale * bmp.getWidth() - getWidth()) / 2;float dy = (scale * bmp.getHeight() - getHeight()) / 2;mMatrix.setTranslate(-dx, -dy);}}// shader的变换矩阵,我们这里主要用于放大或者缩小mMatrix.preScale(scale, scale);mBitmapShader.setLocalMatrix(mMatrix);// 设置变换矩阵mBitmapShader.setLocalMatrix(mMatrix);// 设置shadermBitmapPaint.setShader(mBitmapShader);}/*** drawable转bitmap*/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;}/*** 设置图片类型:* imageType=0 圆形图片* imageType=1 圆角图片* 默认为圆形图片*/public NiceImageView setType(int imageType) {if (this.type != imageType) {this.type = imageType;if (this.type != TYPE_ROUND && this.type != TYPE_CIRCLE && this.type != TYPE_OVAL) {this.type = TYPE_OVAL;}requestLayout();}return this;}/*** 设置圆角图片的圆角大小*/public NiceImageView setCornerRadius(int cornerRadius) {cornerRadius = dp2px(cornerRadius);if (mCornerRadius != cornerRadius) {mCornerRadius = cornerRadius;invalidate();}return this;}/*** 设置圆角图片的左上圆角大小*/public NiceImageView setLeftTopCornerRadius(int cornerRadius) {cornerRadius = dp2px(cornerRadius);if (mLeftTopCornerRadius != cornerRadius) {mLeftTopCornerRadius = cornerRadius;invalidate();}return this;}/*** 设置圆角图片的右上圆角大小*/public NiceImageView setRightTopCornerRadius(int cornerRadius) {cornerRadius = dp2px(cornerRadius);if (mRightTopCornerRadius != cornerRadius) {mRightTopCornerRadius = cornerRadius;invalidate();}return this;}/*** 设置圆角图片的左下圆角大小*/public NiceImageView setLeftBottomCornerRadius(int cornerRadius) {cornerRadius = dp2px(cornerRadius);if (mLeftBottomCornerRadius != cornerRadius) {mLeftBottomCornerRadius = cornerRadius;invalidate();}return this;}/*** 设置圆角图片的右下圆角大小*/public NiceImageView setRightBottomCornerRadius(int cornerRadius) {cornerRadius = dp2px(cornerRadius);if (mRightBottomCornerRadius != cornerRadius) {mRightBottomCornerRadius = cornerRadius;invalidate();}return this;}/*** 设置描边宽度*/public NiceImageView setBorderWidth(int borderWidth) {borderWidth = dp2px(borderWidth);if (mBorderWidth != borderWidth) {mBorderWidth = borderWidth;invalidate();}return this;}/*** 设置描边颜色*/public NiceImageView setBorderColor(int borderColor) {if (mBorderColor != borderColor) {mBorderColor = borderColor;invalidate();}return this;}private int dp2px(int dpVal) {return (int) TypedValue.applyDimension(PLEX_UNIT_DIP,dpVal, getResources().getDisplayMetrics());}}

在values下创建attrs.xml,为控件的属性

<resources><declare-styleable name="NiceImageView"><!-- 描边宽度--><attr name="border_width" format="dimension" /><!-- 描边颜色--><attr name="border_color" format="color" /><!--圆角大小--><attr name="corner_radius" format="dimension" /><!--左上圆角大小--><attr name="leftTop_corner_radius" format="dimension" /><!--右上圆角大小--><attr name="rightTop_corner_radius" format="dimension" /><!--左下圆角大小--><attr name="leftBottom_corner_radius" format="dimension" /><!--右下圆角大小--><attr name="rightBottom_corner_radius" format="dimension" /><!--图片类型:圆角或者圆形--><attr name="type" format="enum"><enum name="oval" value="2" /><enum name="round" value="1" /><enum name="circle" value="0" /></attr></declare-styleable></resources>

第二种:

public class RoundImageView extends ImageView {/*** 图片的类型,圆形or圆角*/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;/*** 绘图的Paint*/private Paint mBitmapPaint;/*** 圆角的半径*/private int mRadius;/*** 3x3 矩阵,主要用于缩小放大*/private Matrix mMatrix;/*** 渲染图像,使用图像为绘制图形着色*/private BitmapShader mBitmapShader;/*** view的宽度*/private int mWidth;private RectF mRoundRect;public RoundImageView(Context context, AttributeSet attrs) {super(context, 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(PLEX_UNIT_DIP,BODER_RADIUS_DEFAULT, getResources().getDisplayMetrics()));// 默认为10dptype = a.getInt(R.styleable.RoundImageView_type, TYPE_CIRCLE);// 默认为Circlea.recycle();}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){Log.e("TAG", "onMeasure");super.onMeasure(widthMeasureSpec, heightMeasureSpec);/** 如果类型是圆形,则强制改变view的宽高一致,以小值为准 */if (type == TYPE_CIRCLE){mWidth = Math.min(getMeasuredWidth(), getMeasuredHeight());mRadius = mWidth / 2;setMeasuredDimension(mWidth, mWidth);}}/** 初始化BitmapShader */private void setUpShader(){Drawable drawable = getDrawable();if (drawable == null){return;}Bitmap bmp = drawableToBitamp(drawable);// 将bmp作为着色器,就是在指定区域内绘制bmpmBitmapShader = 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);// 设置shadermBitmapPaint.setShader(mBitmapShader);}/** drawable转bitmap */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;}@Overrideprotected 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);// drawSomeThing(canvas);}}@Overrideprotected 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());}private static final String STATE_INSTANCE = "state_instance";private static final String STATE_TYPE = "state_type";private static final String STATE_BORDER_RADIUS = "state_border_radius";@Overrideprotected Parcelable onSaveInstanceState(){Bundle bundle = new Bundle();bundle.putParcelable(STATE_INSTANCE, super.onSaveInstanceState());bundle.putInt(STATE_TYPE, type);bundle.putInt(STATE_BORDER_RADIUS, mBorderRadius);return bundle;}@Overrideprotected void onRestoreInstanceState(Parcelable state){if (state instanceof Bundle){Bundle bundle = (Bundle) state;super.onRestoreInstanceState(((Bundle) state).getParcelable(STATE_INSTANCE));this.type = bundle.getInt(STATE_TYPE);this.mBorderRadius = bundle.getInt(STATE_BORDER_RADIUS);} else{super.onRestoreInstanceState(state);}}}

<resources><declare-styleable name="RoundImageView"><attr name="borderRadius" /><attr name="type" /></declare-styleable></resources>

第一种加载时会有部分图片下半部分模糊问题,但它可设置四角圆角大小和背景圈

第二种显示无问题,就是只能设置圆形和整体圆角,没单个设置的,可分情况使用

谢谢观看,拜~

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。