Android绘图最基本的三个对象Color, Canvas, Paint, 均在android.graphics包下。
1) Color : 颜色对象 ----> 颜料
Color.颜色名,来获取颜色。
argb方法,可以调出颜色。
2) Paint : 画笔对象 ----> 画笔
Paint的设置方法 | |||
---|---|---|---|
setAntiAlas() | 设置画笔的锯齿效果 | setColor() | 设置画笔颜色 |
setARGB() | 设置画笔的a,r,g,b值 | setAlpha() | 设置Alpha值 |
setTextSize() | 设置字体尺寸 | setStyle() | 设置画笔风格,空心或实心 |
setStokeWidth() | 设置空心的边框宽度 | getColor() | 得到画笔的颜色 |
getAlpha() | 得到画笔的Alpha值 |
3) Canvas : 画布对象 ----> 画板
Canvas绘制常见方法 | |
---|---|
drawLine() | 绘制直线 |
drawRect() | 绘制矩形 |
drawCircle() | 绘制圆形 |
Start from Here....
现在想完成一个简单的Chrome的logo的绘制,需要完成下图这样的效果:
代码如下:
方案一:最复杂的方法
public class CanvasView extends View {
private int cx;
private int cy;
public CanvasView(Context context) {
super(context);
}
@Override
protected void onDraw(Canvas canvas) {
cx = getMeasuredWidth() / 2;
cy = getMeasuredHeight() / 2;
int innerCr = DensityUtils.dip2px(getContext(), 45);
int outerCr = DensityUtils.dip2px(getContext(), 50);
int wholeCr = DensityUtils.dip2px(getContext(), 100);
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.FILL);
paint.setStrokeWidth(1);
//将整个背景填充为灰色
paint.setColor(Color.GRAY);
canvas.drawPaint(paint);
Path path = new Path();
RectF innerRectF = new RectF(cx - outerCr, cy - outerCr, cx + outerCr, cy + outerCr);
RectF outerRectF = new RectF(cx - wholeCr, cy - wholeCr, cx + wholeCr, cy + wholeCr);
//红色叶瓣
path.addArc(innerRectF, 150, 120);
path.lineTo((float)(cx + Math.sqrt(3.0) * outerCr), cy - outerCr);
path.addArc(outerRectF, -30, -120);
path.lineTo((float)(cx - Math.sqrt(3.0) * outerCr / 2), cy + outerCr / 2);
paint.setColor(Color.RED);
canvas.drawPath(path, paint);
path.reset();
//黄色叶瓣
path.addArc(innerRectF, 30, -120);
path.lineTo((float)(cx + Math.sqrt(3.0) * outerCr), cy - outerCr);
path.addArc(outerRectF, -30, 120);
path.lineTo((float)(cx + Math.sqrt(3.0) * outerCr / 2), cy + outerCr / 2);
paint.setColor(Color.YELLOW);
canvas.drawPath(path, paint);
path.reset();
//绿色叶瓣
path.addArc(innerRectF, 150, -120);
path.lineTo(cx, cy + wholeCr);
path.addArc(outerRectF, 90, 120);
path.lineTo((float)(cx - Math.sqrt(3.0) * outerCr / 2), cy + outerCr / 2);
paint.setColor(Color.GREEN);
canvas.drawPath(path, paint);
path.reset();
//中心的圆
drawCenterCircle(paint, canvas, outerCr, innerCr);
super.onDraw(canvas);
}
private void drawCenterCircle(Paint paint, Canvas canvas, int outerCircleR, int innerCircleR){
paint.setColor(Color.WHITE);
canvas.drawCircle(cx, cy, outerCircleR, paint);//绘制白色外圆
paint.setColor(Color.BLUE);
canvas.drawCircle(cx, cy, innerCircleR, paint);//绘制蓝色内圆
}
}
方案二:旋转canvas。
//红色叶瓣
path.addArc(innerRectF, 150, 120);
path.lineTo((float)(cx + Math.sqrt(3.0) * outerCr), cy - outerCr);
path.addArc(outerRectF, -30, -120);
path.lineTo((float)(cx - Math.sqrt(3.0) * outerCr / 2), cy + outerCr / 2);
paint.setColor(Color.RED);
canvas.drawPath(path, paint);
//黄色叶瓣
canvas.rotate(120, cx, cy);
paint.setColor(Color.YELLOW);
canvas.drawPath(path, paint);
//绿色叶瓣
canvas.rotate(120, cx, cy);
paint.setColor(Color.GREEN);
canvas.drawPath(path, paint);
方案三:旋转path。
//红色叶瓣
path.addArc(innerRectF, 150, 120);
path.lineTo((float)(cx + Math.sqrt(3.0) * outerCr), cy - outerCr);
path.addArc(outerRectF, -30, -120);
path.lineTo((float)(cx - Math.sqrt(3.0) * outerCr / 2), cy + outerCr / 2);
paint.setColor(Color.RED);
canvas.drawPath(path, paint);
Matrix matrix = new Matrix();
matrix.setRotate(120, cx, cy);
//黄色叶瓣
path.transform(matrix);
paint.setColor(Color.YELLOW);
canvas.drawPath(path, paint);
//绿色叶瓣
path.transform(matrix);
paint.setColor(Color.GREEN);
canvas.drawPath(path, paint);
效果如下:
附录:(一些项目中遇到的小问题)
Android中dp和px之间进行转换:
import android.content.Context;
public class DensityUtil {
//根据手机的分辨率从 dp 的单位 转成为 px(像素)
public static int dip2px(Context context, float dpValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
//根据手机的分辨率从 px(像素) 的单位 转成为 dp
public static int px2dip(Context context, float pxValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (pxValue / scale + 0.5f);
}
}
Android绘图抗锯齿:
方法1:
给Paint加上抗锯齿标志。然后将Paint对象作为参数传给canvas的绘制方法。
paint.setAntiAlias(true);
方法2:
给Canvas加上抗锯齿标志。有些地方不能用paint的,就直接给canvas加抗锯齿,更方便。
canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG|Paint.FILTER_BITMAP_FLAG));
Canvas中rotate()方法的理解:
画图的canvas和显示没有关系。当canvas旋转后,绘制的图形还是只能在canvas内,并且坐标是按照canvas旋转之前来的,也就是左上角坐标仍然是(0,0),右下角的坐标仍然是(width,height)。也就是说旋转canvas的时候,画布的坐标系也会跟着旋转。