先来看一下Canvas
Canvas 用来提供draw方法的调用。绘制东西需要4个基本的组建:一个bitmap用来存放像素,一个canvas用来提供draw方法的调用(往bitmap里写入),原始绘制元素(e.g.Rect, Path, text,Bitmap), 一个paint。
看一下canvas的主要方法:
- canvas.save()保存canvas的状态,保存之后,可以调用canvas的平移、缩放、旋转、错切、裁剪等操作。
- canvas.restore();恢复canvas之前保存的状态。
- canvas.translate(x,y);移动坐标原点到指定位置。
- canvas.drawArc();绘制圆弧。
- canvas.drawText();绘制文本。
- canvas.drawLine();绘制线段。
canvas.drawRect();绘制矩形。
Paint类
Paint 类提供绘制几何图形,文本,和位图 所需要的样式和颜色信息。
paint的主要方法:paint.setAntiAlias()抗锯齿。
- paint.setStrokeWidth() 设置画笔的宽度。
- paint.setStyle()设置空心。
- paint.setDither()设置防抖动。
### HappinessView.java
public class HappinessView extends View {
private static final float CIRCLE_RADIUS = 100f;
private static final float faceRadiusToEyeRadiusRadio = 10f;
private static final float faceRadiusToEyeOffsetRadio = 3f;
private static final float faceRadiusToEyeSeparationRadio = 1.5f;
private static final float faceRadiusToMouthWidthRadio = 1;
private static final float faceRadiusToMouthHeightRadio = 3;
private static final float faceRadiusToMouthOffsetRatio = 3;
private enum Eye{ Left, Right}
public HappinessView(Context context) {
super(context);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint();
paint.setStyle(Paint.Style.STROKE);
paint.setAntiAlias(true);
paint.setColor(Color.BLUE);
canvas.drawCircle(100, 100, CIRCLE_RADIUS, paint);
circlePathForEye(canvas, paint, Eye.Left);
circlePathForEye(canvas, paint, Eye.Right);
bezierPathForSmile(canvas, paint);
}
private void bezierPathForSmile(Canvas canvas, Paint paint) {
float fractionOfMaxSmile = -1f;
float mouthWidth = CIRCLE_RADIUS / faceRadiusToMouthWidthRadio;
float mouthHeight = CIRCLE_RADIUS / faceRadiusToMouthHeightRadio;
float mouthVerticalOffset = CIRCLE_RADIUS / faceRadiusToMouthOffsetRatio;
float smileHeight = Math.max(Math.min(fractionOfMaxSmile, 1), -1) * mouthHeight;
float startPointX = 100 - mouthWidth / 2;
float startPointY = 100 + mouthVerticalOffset;
float endPointX = startPointX + mouthWidth;
float endPointY = startPointY;
float point1X = startPointX + mouthWidth / 3;
float point1Y = startPointY + smileHeight;
float point2X = endPointX - mouthWidth / 3;
float point2Y = point1Y;
Path path = new Path();
path.moveTo(startPointX, startPointY);
path.cubicTo( point1X, point1Y, point2X, point2Y, endPointX, endPointY);
canvas.drawPath(path, paint);
}
private void circlePathForEye(Canvas canvas, Paint paint, Eye eye){
float eyeRadius = 100 / faceRadiusToEyeRadiusRadio;
float eyeVerticalOffset = 100 / faceRadiusToEyeOffsetRadio;
float eyeHorizontalSeparation = 100 / faceRadiusToEyeSeparationRadio;
float eyeY = 100 - eyeVerticalOffset;
float eyeX = 100;
switch (eye) {
case Left:
eyeX = eyeX - eyeHorizontalSeparation / 2;
break;
case Right:
eyeX = eyeX + eyeHorizontalSeparation / 2;
break;
}
canvas.drawCircle(eyeX, eyeY, eyeRadius, paint);
}
}
一个简单的笑脸图形。