自定义View将圆角矩形绘制在Canvas上

前几天,公司一个项目中,头像图片需要添加圆角,这样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


你可能感兴趣的:(自定义View将圆角矩形绘制在Canvas上)