Android BitmapShader 实现圆角图形,或圆图
2015-04-11 10:54
134 查看
今天我们要用ImageView的继承类来实现这个效果,依然属于自定义范畴!
既然是自定义,那我们就来复习一下自定义的基本步骤吧:
1,自定义属性
2,在构造方法中获取自定义属性值
3,重写onMeasure方法,调整布局
4,重写onDraw方法绘图。
首先我们先看一下效果图吧,如果觉得效果图很臭,那就没有看下去的必要了!
到了这里,我就不废话了!开始附上我的代码了!
一,自定义属性,
1,type属性,来判断图片是圆角图,还是原图(即是第一个图的样式,还是第二个图的样式),type的值我用了枚举类型
2,bitmapRadius,如果是圆角,则圆角半径的值
二,在构造方法中拿到属性的值,并初始化矩阵对象了mMatrix,和画笔对象mPaint
三在onMeasure中调整控件宽高
因为圆图的话,高宽是相等的,这里取了两者的较小值!
四,onDraw方法中绘图
1,先得到图对象,并把图对象Drawable封装到位图对象Bitmap中!
2,得到位图对象后,利用Matrix按比例缩放图像(这里就用到了bitmapShader对象)
3,最后才是绘制图像
1,的实现方法:
2,的实现方法:
3,的实现方法:
五,为了解决动态设置的属性,在屏幕发生旋转或者所在Activity久置后台后会重新绘制,这时之前设置的属性就会丢失的问题
我又重写了。onSaveInstanceState方法和onRestoreInstanceState方法
源代码下载
既然是自定义,那我们就来复习一下自定义的基本步骤吧:
1,自定义属性
2,在构造方法中获取自定义属性值
3,重写onMeasure方法,调整布局
4,重写onDraw方法绘图。
首先我们先看一下效果图吧,如果觉得效果图很臭,那就没有看下去的必要了!
到了这里,我就不废话了!开始附上我的代码了!
一,自定义属性,
1,type属性,来判断图片是圆角图,还是原图(即是第一个图的样式,还是第二个图的样式),type的值我用了枚举类型
2,bitmapRadius,如果是圆角,则圆角半径的值
<?xml version="1.0" encoding="utf-8"?> <resources> <attr name="borderRadius" format="dimension" /> <attr name="type"> <enum name="circle" value="0" /> <enum name="round" value="1" /> </attr> <declare-styleable name="RoundImageView"> <attr name="borderRadius" /> <attr name="type" /> </declare-styleable> </resources>
二,在构造方法中拿到属性的值,并初始化矩阵对象了mMatrix,和画笔对象mPaint
private int type;// 自定义图片的类型 0,为圆角形,1,为圆形 private static final int TYPE_ROUND = 0; private static final int TYPE_CIRCLE = 1; private int bitmapRadius;// 圆角的半径 private static final int RADIUS_DEFAULT = 10; private int radius;//圆的半径 private Paint mPaint;// 画笔对象 private BitmapShader mShader;// 图形控制 private Matrix mMatrix;//矩阵对象用于缩放图片 //view的大小 private int mWidth; private RectF mRectF; /** * 第二步 * @param context */ public CustomImageView1(Context context) { this(context, null, 0); } public CustomImageView1(Context context, AttributeSet attrs) { this(context, attrs, 0); } public CustomImageView1(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); TypedArray typeArray=context .obtainStyledAttributes(attrs,R.styleable.CustomImageView); //默认为10dip bitmapRadius=typeArray.getDimensionPixelOffset(R.styleable.CustomImageView_radiusRadius, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, RADIUS_DEFAULT, getResources().getDisplayMetrics())); //默认为圆 type=typeArray.getInt(R.styleable.CustomImageView_type, TYPE_CIRCLE); typeArray.recycle(); mMatrix=new Matrix(); mPaint=new Paint(); mPaint.setAntiAlias(true);//消除锯齿 }
三在onMeasure中调整控件宽高
因为圆图的话,高宽是相等的,这里取了两者的较小值!
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); if(type==TYPE_CIRCLE){ mWidth=Math.min(getMeasuredWidth(), getMeasuredHeight()); radius=mWidth/2; setMeasuredDimension(mWidth, mWidth); } }
四,onDraw方法中绘图
1,先得到图对象,并把图对象Drawable封装到位图对象Bitmap中!
2,得到位图对象后,利用Matrix按比例缩放图像(这里就用到了bitmapShader对象)
3,最后才是绘制图像
1,的实现方法:
private Bitmap drawableToBitmap(){ Drawable drawable=getDrawable(); if(drawable==null){ return null; } 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); //将图片画在画布canvas上,并放在容器bitmap中 drawable.draw(canvas); return bitmap; }
2,的实现方法:
private void setUpBitmapShaper(){ Bitmap bitmap=drawableToBitmap(); if(bitmap==null){ return; } mShader=new BitmapShader(bitmap, TileMode.CLAMP, TileMode.CLAMP); float scale; if(type==TYPE_CIRCLE){ //圆形 scale=mWidth*1.0f/Math.min(bitmap.getWidth(), bitmap.getHeight()); }else{ //圆角形 scale=Math.max(getWidth()*1.0f/bitmap.getWidth()*1.0f , getHeight()*1.0f/bitmap.getHeight()*1.0f); } mMatrix.setScale(scale,scale); mShader.setLocalMatrix(mMatrix); mPaint.setShader(mShader); }
3,的实现方法:
@Override protected void onDraw(Canvas canvas) { if(getDrawable()==null){ return; } setUpBitmapShaper(); if(type==TYPE_CIRCLE){ canvas.drawCircle(radius, radius, radius, mPaint); }else{ canvas.drawRoundRect(mRectF,bitmapRadius, bitmapRadius, mPaint); } //canvas.drawCircle(cx, cy, RADIUS_DEFAULT, paint); }
五,为了解决动态设置的属性,在屏幕发生旋转或者所在Activity久置后台后会重新绘制,这时之前设置的属性就会丢失的问题
我又重写了。onSaveInstanceState方法和onRestoreInstanceState方法
private static final String STATE_INSTANCE="state_instance"; private static final String STATE_TYPE="state_type"; private static final String STATE_RADIUS="state_radius"; //只有需要reCreate一個Activity時,才会去调用它,比如,横竖切屏,改变语言,activity久置后台重新启动 @Override protected Parcelable onSaveInstanceState() { Bundle bd=new Bundle(); bd.putParcelable(STATE_INSTANCE, super.onSaveInstanceState()); bd.putInt(STATE_TYPE, type); bd.putInt(STATE_RADIUS, bitmapRadius); return bd; } @Override protected void onRestoreInstanceState(Parcelable state) { if(state instanceof Bundle){ Bundle bd=(Bundle) state; super.onRestoreInstanceState(bd.getParcelable(STATE_INSTANCE)); type=bd.getInt(STATE_TYPE); bitmapRadius=bd.getInt(STATE_RADIUS); }else{ super.onRestoreInstanceState(state); } }
源代码下载
相关文章推荐
- Android自定义view实现圆形、圆角和椭圆图片(BitmapShader图形渲染)
- Android 自定义View修炼-Android实现圆形、圆角和椭圆自定义图片View(使用BitmapShader图形渲染方法)
- Android使用BitmapShader图形渲染实现圆形、圆角和椭圆自定义图片View
- Android BitmapShader实现圆形和圆角图片
- Android BitmapShader 实战 实现圆形、圆角图片
- Android BitmapShader 实战 实现圆形、圆角图片
- Android BitmapShader实现圆形和圆角图片
- Android BitmapShader 实战 实现圆形、圆角图片
- Android BitmapShader实现圆形和圆角图片
- Android BitmapShader 实战 实现圆形、圆角图片
- Android BitmapShader 实战 实现圆形、圆角图片
- Android BitmapShader 实现圆形、圆角图片
- Android BitmapShader 实战 实现圆形、圆角图片——代码分析
- Android BitmapShader 实战 实现圆形、圆角图片
- Android BitmapShader实现圆形和圆角图片
- Android BitmapShader 实战 实现圆形、圆角图片
- Android BitmapShader 实战 实现圆形、圆角图片
- Android BitmapShader 实战 实现圆形、圆角图片
- Android自定义View【实战教程】4⃣️----BitmapShader详解及圆形、圆角、多边形实现
- 【转】Android BitmapShader 实战 实现圆形、圆角图片