Canvas 代表“依附”于指定 View 的画布
Canvas 的绘制方法
image.pngPaint 代表 Canvas 上的画笔,主要用于设置绘制风格,包括画笔颜色、画笔笔触粗细、填充风格等。
Paint 的常用方法
image.pngPath 代表任意多条直线连接而成的任意图形。
public class MyView extends View {
private Path path1 = new Path();
private Path path2 = new Path();
private Path path3 = new Path();
private Path path4 = new Path();
private Path path5 = new Path();
private Path path6 = new Path();
public MyView(Context context, AttributeSet set) {
super(context, set);
}
private LinearGradient mShader = new LinearGradient(0f, 0f, 40f, 60f,
new int[]{Color.RED, Color.GREEN, Color.BLUE, Color.YELLOW},
null, Shader.TileMode.REPEAT);
private RectF rect = new RectF();
// 定义画笔
private Paint paint = new Paint();
// 重写该方法,进行绘图
@Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 把整张画布绘制成白色
canvas.drawColor(Color.WHITE);
// 去锯齿
paint.setAntiAlias(true);
paint.setColor(Color.BLUE);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(4f);
int viewWidth = this.getWidth();
// 绘制圆形
canvas.drawCircle(viewWidth / 10 + 10, viewWidth / 10 + 10, viewWidth / 10, paint);
// 绘制正方形
canvas.drawRect(10f, viewWidth / 5 + 20,
viewWidth / 5 + 10, viewWidth * 2 / 5 + 20, paint);
// 绘制矩形
canvas.drawRect(10f, viewWidth * 2 / 5 + 30,
viewWidth / 5 + 10, viewWidth / 2 + 30, paint);
rect.set(10f, viewWidth / 2 + 40, 10 + viewWidth / 5, viewWidth * 3 / 5 + 40);
// 绘制圆角矩形
canvas.drawRoundRect(rect, 15f, 15f, paint);
rect.set(10f, viewWidth * 3 / 5 + 50, 10 + viewWidth / 5, viewWidth * 7 / 10 + 50);
// 绘制椭圆
canvas.drawOval(rect, paint);
// 使用一个Path对象封闭成一个三角形
path1.moveTo(10f, viewWidth * 9 / 10 + 60);
path1.lineTo(viewWidth / 5 + 10, viewWidth * 9 / 10 + 60);
path1.lineTo(viewWidth / 10 + 10, viewWidth * 7 / 10 + 60);
path1.close();
// 根据Path进行绘制,绘制三角形
canvas.drawPath(path1, paint);
// 使用一个Path对象封闭成一个五角形
path2.moveTo(10 + viewWidth / 15, viewWidth * 9 / 10 + 70);
path2.lineTo(10 + viewWidth * 2 / 15, viewWidth * 9 / 10 + 70);
path2.lineTo(10 + viewWidth / 5, viewWidth + 70);
path2.lineTo(10 + viewWidth / 10, viewWidth * 11 / 10 + 70);
path2.lineTo(10f, viewWidth + 70);
path2.close();
// 根据Path进行绘制,绘制五角形
canvas.drawPath(path2, paint);
// ----------设置填充风格后绘制----------
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.RED);
// 绘制圆形
canvas.drawCircle(viewWidth * 3 / 10 + 20, viewWidth / 10 + 10, viewWidth / 10, paint);
// 绘制正方形
canvas.drawRect(viewWidth / 5 + 20, viewWidth / 5 + 20,
viewWidth * 2 / 5 + 20, viewWidth * 2 / 5 + 20, paint);
// 绘制矩形
canvas.drawRect(viewWidth / 5 + 20, viewWidth * 2 / 5 + 30,
viewWidth * 2 / 5 + 20, viewWidth / 2 + 30, paint);
rect.set(viewWidth / 5 + 20, viewWidth / 2 + 40,
20 + viewWidth * 2 / 5, viewWidth * 3 / 5 + 40);
// 绘制圆角矩形
canvas.drawRoundRect(rect, 15f, 15f, paint);
rect.set(20 + viewWidth / 5, viewWidth * 3 / 5 + 50,
20 + viewWidth * 2 / 5, viewWidth * 7 / 10 + 50);
// 绘制椭圆
canvas.drawOval(rect, paint);
// 使用一个Path对象封闭成一个三角形
path3.moveTo(20 + viewWidth / 5, viewWidth * 9 / 10 + 60);
path3.lineTo(viewWidth * 2 / 5 + 20, viewWidth * 9 / 10 + 60);
path3.lineTo(viewWidth * 3 / 10 + 20, viewWidth * 7 / 10 + 60);
path3.close();
// 根据Path进行绘制,绘制三角形
canvas.drawPath(path3, paint);
// 使用一个Path对象封闭成一个五角形
path4.moveTo(20 + viewWidth * 4 / 15, viewWidth * 9 / 10 + 70);
path4.lineTo(20 + viewWidth / 3, viewWidth * 9 / 10 + 70);
path4.lineTo(20 + viewWidth * 2 / 5, viewWidth + 70);
path4.lineTo(20 + viewWidth * 3 / 10, viewWidth * 11 / 10 + 70);
path4.lineTo(20 + viewWidth / 5, viewWidth + 70);
path4.close();
// 根据Path进行绘制,绘制五角形
canvas.drawPath(path4, paint);
// ----------设置渐变器后绘制----------
// 为Paint设置渐变器
paint.setShader(mShader);
// 设置阴影
paint.setShadowLayer(25f, 20f, 20f, Color.GRAY);
// 绘制圆形
canvas.drawCircle(viewWidth / 2 + 30, viewWidth / 10 + 10, viewWidth / 10, paint);
// 绘制正方形
canvas.drawRect(viewWidth * 2 / 5 + 30, viewWidth / 5 + 20,
viewWidth * 3 / 5 + 30, viewWidth * 2 / 5 + 20, paint);
// 绘制矩形
canvas.drawRect(viewWidth * 2 / 5 + 30, viewWidth * 2 / 5 + 30,
viewWidth * 3 / 5 + 30, viewWidth / 2 + 30, paint);
rect.set((viewWidth * 2 / 5 + 30), viewWidth / 2 + 40, 30 + viewWidth * 3 / 5,
viewWidth * 3 / 5 + 40);
// 绘制圆角矩形
canvas.drawRoundRect(rect, 15f, 15f, paint);
rect.set(30 + viewWidth * 2 / 5, viewWidth * 3 / 5 + 50, 30 + viewWidth * 3 / 5,
viewWidth * 7 / 10 + 50);
// 绘制椭圆
canvas.drawOval(rect, paint);
// 使用一个Path对象封闭成一个三角形
path5.moveTo(30 + viewWidth * 2 / 5, viewWidth * 9 / 10 + 60);
path5.lineTo(viewWidth * 3 / 5 + 30, viewWidth * 9 / 10 + 60);
path5.lineTo(viewWidth / 2 + 30, viewWidth * 7 / 10 + 60);
path5.close();
// 根据Path进行绘制,绘制三角形
canvas.drawPath(path5, paint);
// 使用一个Path对象封闭成一个五角形
path6.moveTo(30 + viewWidth * 7 / 15, viewWidth * 9 / 10 + 70);
path6.lineTo(30 + viewWidth * 8 / 15, viewWidth * 9 / 10 + 70);
path6.lineTo(30 + viewWidth * 3 / 5, viewWidth + 70);
path6.lineTo(30 + viewWidth / 2, viewWidth * 11 / 10 + 70);
path6.lineTo(30 + viewWidth * 2 / 5, viewWidth + 70);
path6.close();
// 根据Path进行绘制,绘制五角形
canvas.drawPath(path6, paint);
// ----------设置字符大小后绘制----------
paint.setTextSize(48f);
paint.setShader(null);
// 绘制7个字符串
canvas.drawText(getResources().getString(R.string.circle),
60 + viewWidth * 3 / 5, viewWidth / 10 + 10, paint);
canvas.drawText(getResources().getString(R.string.square),
60 + viewWidth * 3 / 5, viewWidth * 3 / 10 + 20, paint);
canvas.drawText(getResources().getString(R.string.rect),
60 + viewWidth * 3 / 5, viewWidth * 1 / 2 + 20, paint);
canvas.drawText(getResources().getString(R.string.round_rect),
60 + viewWidth * 3 / 5, viewWidth * 3 / 5 + 30, paint);
canvas.drawText(getResources().getString(R.string.oval),
60 + viewWidth * 3 / 5, viewWidth * 7 / 10 + 30, paint);
canvas.drawText(getResources().getString(R.string.triangle),
60 + viewWidth * 3 / 5, viewWidth * 9 / 10 + 30, paint);
canvas.drawText(getResources().getString(R.string.pentagon),
60 + viewWidth * 3 / 5, viewWidth * 11 / 10 + 30, paint);
}
}
image.png
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new MyView(this));
}
private static class MyView extends View {
private float phase;
private PathEffect[] effects = new PathEffect[7];
private int[] colors;
private Paint paint = new Paint();
// 定义创建并初始化Path
private Path path = new Path();
public MyView(Context context) {
super(context);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(4);
path.moveTo(0f, 0f);
for (int i = 1; i <= 40; i++) {
// 生成40个点,随机生成它们的Y坐标,并将它们连成一条Path
path.lineTo(i * 25f, (float) (Math.random() * 90));
}
// 初始化7种颜色
colors = new int[]{Color.BLACK, Color.BLUE, Color.CYAN,
Color.GREEN, Color.MAGENTA, Color.RED, Color.YELLOW};
// -----------下面开始初始化7种路径效果----------
// 不使用路径效果
effects[0] = null;
// 使用CornerPathEffect路径效果
effects[1] = new CornerPathEffect(10f);
// 初始化DiscretePathEffect
effects[2] = new DiscretePathEffect(3.0f, 5.0f);
}
@Override
public void onDraw(Canvas canvas) {
// 将背景填充成白色
canvas.drawColor(Color.WHITE);
// 将画布移动到(8, 8)处开始绘制
canvas.translate(8f, 8f);
// 依次使用7种不同的路径效果、7种不同的颜色来绘制路径
for (int i = 0; i < effects.length; i++) {
paint.setPathEffect(effects[i]);
paint.setColor(colors[i]);
canvas.drawPath(path, paint);
canvas.translate(0f, 90f);
}
// 初始化DashPathEffect
effects[3] = new DashPathEffect(new float[]{20f, 10f, 5f, 10f}, phase);
// 初始化PathDashPathEffect
Path p = new Path();
p.addRect(0f, 0f, 8f, 8f, Path.Direction.CCW);
effects[4] = new PathDashPathEffect(p, 12f, phase,
PathDashPathEffect.Style.ROTATE);
// 初始化ComposePathEffect
effects[5] = new ComposePathEffect(effects[2], effects[4]);
effects[6] = new SumPathEffect(effects[4], effects[3]);
// 改变phase值,形成动画效果
phase += 1f;
invalidate();
}
}
}
image.gif
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new PathTextView(this));
}
private static class PathTextView extends View {
private String drawStr = getResources().getString(R.string.draw_string);
private Path[] paths = new Path[3];
private Paint paint = new Paint();
public PathTextView(Context context) {
super(context);
paths[0] = new Path();
paths[0].moveTo(0f, 0f);
for (int i = 1; i <= 20; i++) {
// 生成20个点,随机生成它们的Y坐标,并将它们连成一条Path
paths[0].lineTo(i * 30f, (float) (Math.random() * 30));
}
paths[1] = new Path();
RectF rectF = new RectF(0f, 0f, 600f, 360f);
paths[1].addOval(rectF, Path.Direction.CCW);
paths[2] = new Path();
paths[2].addArc(rectF, 60f, 180f);
// 初始化画笔
paint.setAntiAlias(true);
paint.setColor(Color.CYAN);
paint.setStrokeWidth(1f);
}
@Override
public void onDraw(Canvas canvas) {
canvas.drawColor(Color.WHITE);
canvas.translate(40f, 40f);
// 设置从右边开始绘制(右对齐)
paint.setTextAlign(Paint.Align.RIGHT);
paint.setTextSize(30f);
// 绘制路径
paint.setStyle(Paint.Style.STROKE);
canvas.drawPath(paths[0], paint);
paint.setTextSize(40f);
// 沿着路径绘制一段文本
paint.setStyle(Paint.Style.FILL);
canvas.drawTextOnPath(drawStr, paths[0], -8f, 20f, paint);
// 对Canvas进行坐标变换:画布下移60
canvas.translate(0f, 60f);
// 绘制路径
paint.setStyle(Paint.Style.STROKE);
canvas.drawPath(paths[1], paint);
// 沿着路径绘制一段文本
paint.setStyle(Paint.Style.FILL);
canvas.drawTextOnPath(drawStr, paths[1], -20f, 20f, paint);
// 对Canvas进行坐标变换:画布下移360
canvas.translate(0f, 360f);
// 绘制路径
paint.setStyle(Paint.Style.STROKE);
canvas.drawPath(paths[2], paint);
// 沿着路径绘制一段文本
paint.setStyle(Paint.Style.FILL);
canvas.drawTextOnPath(drawStr, paths[2], -10f, 20f, paint);
}
}
}
image.png
摘抄至《疯狂Android讲义(第4版)》
网友评论