前几天,公司一个项目中,头像图片需要添加圆角,这样UI效果会更好看,于是写了一个小的demo进行圆角的定义,该处主要是使用BitmapShader进行了渲染(如果要将一张图片裁剪成椭圆或圆形显示在屏幕上,也可以使用BitmapShader来完成).
BitmapShader类完成渲染图片的基本步骤如下:
1、创建BitmapShader类的对象
/** * Call this to create a new shader that will draw with a bitmap. * * @param bitmap The bitmap to use inside the shader * @param tileX The tiling mode for x to draw the bitmap in. * @param tileY The tiling mode for y to draw the bitmap in. */ public BitmapShader(Bitmap bitmap, TileMode tileX, TileMode tileY) { ...... }
其中,Shader.TitleMode类型有三种,CALMP、MIRROR、REPEAT
CALMP:使用边界颜色来填充剩余空间
MIRROR:使用镜像方式
REPEAT:使用重复方式
2、通过Paint的setShader(bitmapShafer)来设置画笔3、使用已经setShader(bitmapShafer)的画笔来绘制图形
下面展示绘制圆角图片的demo
1、自定义RounderCornerImageView.java类
package com.example.test; import android.content.Context; 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.util.AttributeSet; import android.view.View; public class RounderCornerImageView extends View { private Bitmap mImage;// source bitmap private Paint mBitmapPaint;//paint private RectF mBrounds;//rect private float mRadius=20.0f;//round public RounderCornerImageView(Context context) { this(context, null); } public RounderCornerImageView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public RounderCornerImageView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } private void init() { mBitmapPaint=new Paint(Paint.ANTI_ALIAS_FLAG); mBrounds=new RectF(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // TODO Auto-generated method stub int height,width; height=width=0; //obtain bitmap size int imageHeight,imageWidth; if (null!=mImage) { imageHeight=imageWidth=0; }else { imageHeight=mImage.getHeight(); imageWidth=mImage.getWidth(); } //obtain best measure data and set on View width=getMeasurement(widthMeasureSpec,imageWidth); height=getMeasurement(heightMeasureSpec, imageHeight); //set View last size setMeasuredDimension(width, height); } /** * measure width and height by specMode **/ private int getMeasurement(int measureSpec, int contentSize) { int specSize=MeasureSpec.getSize(measureSpec); switch (MeasureSpec.getMode(measureSpec)) { case MeasureSpec.AT_MOST: return Math.min(specSize, contentSize); case MeasureSpec.UNSPECIFIED: return contentSize; case MeasureSpec.EXACTLY: return specSize; default: return 0; }//switch } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { if (w!=oldw || h!=oldh) { int imageWidth,imageHeight; if (null==mImage) { imageWidth=imageHeight=0; }else { imageWidth=mImage.getWidth(); imageHeight=mImage.getHeight(); } //center point int left=(w-imageWidth)/2; int top=(h-imageHeight)/2; mBrounds.set(left, top, left+imageWidth, top+imageHeight); if (null!=mBitmapPaint.getShader()) { Matrix m=new Matrix(); m.setTranslate(left, top); mBitmapPaint.getShader().setLocalMatrix(m); } } } public void setImage(Bitmap bitmap) { if (mImage!=bitmap) { mImage=bitmap; if (null!=mImage) { BitmapShader shader=new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); mBitmapPaint.setShader(shader); }else { mBitmapPaint.setShader(null); } requestLayout();//invalidated the layout of this view by onDraw() } } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if (null!=mBitmapPaint) { //draw Round Rect canvas.drawRoundRect(mBrounds, mRadius, mRadius, mBitmapPaint); } } }
2、显示圆角图片的RoundActivity.java类
package com.example.test; import android.app.Activity; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Bundle; public class RoundActivity extends Activity{ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); RounderCornerImageView view=new RounderCornerImageView(this); Bitmap souBitmap=BitmapFactory.decodeResource(getResources(), R.drawable.sun); view.setImage(souBitmap); setContentView(view); } }
另外,附注下自定义View的一些基本步骤和必须实现的方法
1、继承view
2、重写自定义View的构造方法
3、如需要对view进行位置进行测量和重写布局,则需要重写onMeasure()、onLayout()、onDraw()方法
onMeasure():view本身大小多少,可以测量出来
onLayout();view在ViewGroup中的位置可以决定
onDraw();定义了如何绘制该view