Android 三种方式实现圆角ImageView
16lz
2021-01-23
所有方式均继承了ImageView
圆角图片实现一:BitmapShader
package com.open.widget;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.TileMode;import android.graphics.drawable.BitmapDrawable;import android.graphics.drawable.Drawable;import android.util.AttributeSet;import android.util.TypedValue;import android.widget.ImageView;import com.open.image.R;/** * 1.BitmapShader * * @author Administrator * */public class RoundImageView extends ImageView {private final int DEFAULT_RADIUS=10;private BitmapShader mBitmapShader;private Paint mBitmapPaint = new Paint();private RectF mRoundRect=new RectF();private int x_radius;private int y_radius;public RoundImageView(Context context) {super(context);initObjectAttribute();}public RoundImageView(Context context, AttributeSet attrs) {this(context, attrs, 0);}public RoundImageView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);initObjectAttribute();final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RoundImageView, defStyleAttr, 0);x_radius=a.getDimensionPixelSize(R.styleable.RoundImageView_x_radius, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,DEFAULT_RADIUS, getResources().getDisplayMetrics()));y_radius=a.getDimensionPixelSize(R.styleable.RoundImageView_y_radius, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,DEFAULT_RADIUS, getResources().getDisplayMetrics()));a.recycle();}private void initObjectAttribute(){mBitmapPaint.setAntiAlias(true);//if(getScaleType() != ScaleType.CENTER_CROP)//{//setScaleType(ScaleType.CENTER_CROP);//}}@Overridepublic void setImageResource(int resId) {super.setImageResource(resId);createBitmapShader();}@Overridepublic void setImageBitmap(Bitmap bm) {super.setImageBitmap(bm);//createBitmapShader();}@Overridepublic void setImageDrawable(Drawable drawable) {super.setImageDrawable(drawable);createBitmapShader();}private void createBitmapShader(){mBitmapShader = null;Drawable mDrawable = getDrawable();if (null == mDrawable){return;}if(mDrawable instanceof BitmapDrawable){BitmapDrawable bd = (BitmapDrawable) mDrawable;Bitmap bitmap = bd.getBitmap();mBitmapShader = new BitmapShader(bitmap, TileMode.CLAMP, TileMode.CLAMP);}else //if Drawable instanceof NinePathDrawable ,the code below is bad , because a view reference two bitmap ( one in NinePath , other is here) {int w = mDrawable.getIntrinsicWidth();int h = mDrawable.getIntrinsicHeight();Bitmap bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);Canvas canvas = new Canvas(bitmap);mDrawable.setBounds(0, 0, w, h);mDrawable.draw(canvas);mBitmapShader = new BitmapShader(bitmap, TileMode.CLAMP, TileMode.CLAMP);}}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);mRoundRect.set(0,0,getMeasuredWidth(),getMeasuredHeight());}@Overrideprotected void onDraw(Canvas canvas) {Drawable mDrawable = getDrawable();if (null == mDrawable || null == mBitmapShader){return;}Matrix mDrawMatrix= getImageMatrix();if(null == mDrawMatrix){mDrawMatrix =new Matrix();}mBitmapShader.setLocalMatrix(mDrawMatrix);mBitmapPaint.setShader(mBitmapShader);canvas.drawRoundRect(mRoundRect, x_radius, y_radius,mBitmapPaint);}}
圆角图片实现二:Path
package com.open.widget;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Canvas;import android.graphics.Matrix;import android.graphics.Path;import android.graphics.RectF;import android.graphics.Region;import android.graphics.drawable.Drawable;import android.util.AttributeSet;import android.util.TypedValue;import android.widget.ImageView;import com.open.image.R;/** * 2.Path * * @author Administrator * */public class RoundImageView2 extends ImageView {private final int DEFAULT_RADIUS=10;private RectF mRoundRect=new RectF();private int x_radius;private int y_radius;private Path mPath = new Path();public RoundImageView2(Context context) {super(context);initObjectAttribute();}public RoundImageView2(Context context, AttributeSet attrs) {this(context, attrs, 0);}public RoundImageView2(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);initObjectAttribute();final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RoundImageView, defStyleAttr, 0);x_radius=a.getDimensionPixelSize(R.styleable.RoundImageView_x_radius, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,DEFAULT_RADIUS, getResources().getDisplayMetrics()));y_radius=a.getDimensionPixelSize(R.styleable.RoundImageView_y_radius, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,DEFAULT_RADIUS, getResources().getDisplayMetrics()));a.recycle();}private void initObjectAttribute(){//if(getScaleType() != ScaleType.CENTER_CROP)//{//setScaleType(ScaleType.CENTER_CROP);//}}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);mRoundRect.set(0,0,getMeasuredWidth(),getMeasuredHeight());}@Overrideprotected void onDraw(Canvas canvas) {Drawable mDrawable = getDrawable();if (mDrawable == null){return;} if (mDrawable.getIntrinsicWidth() == 0 || mDrawable.getIntrinsicHeight() == 0) { return; // nothing to draw (empty bounds) } canvas.save(); mPath.reset(); canvas.clipPath(mPath); // makes the clip empty mPath.addRoundRect(mRoundRect, x_radius, y_radius, Path.Direction.CCW); canvas.clipPath(mPath, Region.Op.REPLACE); Matrix mDrawMatrix = getImageMatrix(); if (mDrawMatrix != null) { canvas.concat(mDrawMatrix); } mDrawable.draw(canvas); canvas.restore();}}
圆角图片实现三:setXfermode
package com.open.widget;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Bitmap;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.PorterDuff;import android.graphics.PorterDuffXfermode;import android.graphics.RectF;import android.graphics.Xfermode;import android.graphics.drawable.Drawable;import android.util.AttributeSet;import android.util.TypedValue;import android.widget.ImageView;import com.open.image.R;/** * 3.setXfermode * * @author Administrator * */public class RoundImageView3 extends ImageView {private final int DEFAULT_RADIUS=10;private Paint paint = new Paint(); private Xfermode mXfermode = new PorterDuffXfermode(PorterDuff.Mode.DST_IN);private Bitmap maskBitmap=null;private RectF mRoundRect=new RectF();private int x_radius;private int y_radius;private int oldWidth;private int oldHeight;public RoundImageView3(Context context) {super(context);initObjectAttribute();}public RoundImageView3(Context context, AttributeSet attrs) {this(context, attrs, 0);}public RoundImageView3(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);initObjectAttribute();final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RoundImageView, defStyleAttr, 0);x_radius=a.getDimensionPixelSize(R.styleable.RoundImageView_x_radius, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,DEFAULT_RADIUS, getResources().getDisplayMetrics()));y_radius=a.getDimensionPixelSize(R.styleable.RoundImageView_y_radius, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,DEFAULT_RADIUS, getResources().getDisplayMetrics()));a.recycle();}private void initObjectAttribute(){ paint.setFlags(Paint.ANTI_ALIAS_FLAG); paint.setAntiAlias(true);// 设置画笔的锯齿效果。 true是去除,大家一看效果就明白了 //if(getScaleType() != ScaleType.CENTER_CROP)//{//setScaleType(ScaleType.CENTER_CROP);//}}private void create_mask_bitmap(int w , int h){if(null != maskBitmap && !maskBitmap.isRecycled()){maskBitmap.recycle();maskBitmap=null;}maskBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); Canvas mCanvas = new Canvas(maskBitmap); Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mPaint.setColor(Color.TRANSPARENT); mCanvas.drawRoundRect(new RectF(0, 0, w, h), x_radius, y_radius, paint);}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);mRoundRect.set(0,0,getMeasuredWidth(),getMeasuredHeight());if( oldWidth!=getMeasuredWidth() || oldHeight!=getMeasuredHeight() ){oldWidth = getMeasuredWidth() ;oldHeight = getMeasuredHeight();if(oldWidth > 0 && oldHeight >0){create_mask_bitmap(oldWidth , oldHeight);}}}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);Drawable mDrawable = getDrawable();if (mDrawable == null){return;} if (mDrawable.getIntrinsicWidth() == 0 || mDrawable.getIntrinsicHeight() == 0) { return; // nothing to draw (empty bounds) } if(null == maskBitmap) { return; } int saveCount = canvas.getSaveCount(); canvas.save(); paint.setFilterBitmap(false); paint.setXfermode(mXfermode); canvas.drawBitmap(maskBitmap, null, mRoundRect, paint); paint.setXfermode(null); canvas.restoreToCount(saveCount);}}
这里主要是重用了ImageView,如果你想强制绘制的View为圆角或者圆形图片,把代码中注释的代码打开即可
private void initObjectAttribute(){mBitmapPaint.setAntiAlias(true);//if(getScaleType() != ScaleType.CENTER_CROP)//{//setScaleType(ScaleType.CENTER_CROP);//}}
知识点不是很难,代码浅显易懂,当然最好去熟读一下ImageView的源码.
源码获取地址:
github : https://github.com/zz7zz7zz/android-image
csdn : http://download.csdn.net/detail/zz7zz7zz/9421399
更多相关文章
- Android 创建与解析XML(五)—— Dom4j方式
- android 图片水平显示,类Gallery效果
- Android 三种方式实现圆形ImageView
- android:软件的安装和卸载源代码
- 向Android社区贡献代码过程详解