您的位置:首页 > 其它

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

2015-11-16 17:22 585 查看
前几天,公司一个项目中,头像图片需要添加圆角,这样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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: