在Android中,Canvas
类是所有图形绘制的核心,它提供了大量的方法用于绘制各种图形元素以及对这些图形进行变换。自定义控件时,熟练掌握Canvas
的变换和操作能力是至关重要的。下面,我们将深入探讨Canvas
的变换与操作,包括平移、缩放、旋转、剪切以及路径绘制,同时提供一些实用的代码示例。
平移(translate)
平移是Canvas
中最基本的变换之一,它通过translate()
方法来实现,可以将坐标原点从左上角移动到指定的位置。这在绘制图形时非常有用,可以让我们更灵活地控制图形在屏幕上的位置。
示例代码:
Java
1canvas.translate(100, 100); // 将坐标原点向右下移动100像素
2paint.setColor(Color.BLUE);
3canvas.drawRect(0, 0, 50, 50, paint); // 在新原点处绘制一个蓝色正方形
缩放(scale)
Canvas
的scale()
方法允许你按比例放大或缩小画布上的内容。这对于实现缩放动画或调整复杂图形的大小特别有用。
示例代码:
Java
1canvas.scale(2, 2); // 将画布内容放大两倍
2paint.setColor(Color.GREEN);
3canvas.drawRect(0, 0, 50, 50, paint); // 绘制一个绿色正方形,实际上是100x100
旋转(rotate)
Canvas
的rotate()
方法可以围绕指定的点旋转画布。这对于实现旋转动画或者需要精确角度定位的图形非常有用。
示例代码:
Java
1canvas.rotate(45, 100, 100); // 以(100, 100)为中心点旋转45度
2paint.setColor(Color.YELLOW);
3canvas.drawRect(0, 0, 50, 50, paint); // 绘制一个黄色正方形,但因旋转而变形
剪切(clip)
Canvas
的clipRect()
方法允许你限制绘图的区域,只在指定的矩形区域内绘制图形。这对于实现复杂的遮罩效果或裁剪图形非常有用。
示例代码:
Java
1canvas.clipRect(50, 50, 150, 150); // 只在50x50至150x150的区域内绘制
2paint.setColor(Color.CYAN);
3canvas.drawRect(0, 0, 200, 200, paint); // 实际上只绘制出100x100的正方形
路径绘制(Path)
Path
类提供了丰富的功能来创建复杂的图形路径,如直线、曲线、圆弧等。结合Canvas
,可以绘制出极其复杂的图形。
示例代码:
Java
1Path path = new Path();
2path.moveTo(50, 50);
3path.lineTo(100, 100);
4path.lineTo(150, 50);
5path.close(); // 形成一个三角形
6paint.setColor(Color.MAGENTA);
7canvas.drawPath(path, paint);
复合变换
在实际应用中,我们经常需要复合使用多种变换。Canvas
提供了save()
和restore()
方法来保存和恢复变换状态,这样可以避免变换的累积效应。
示例代码:
Java
1canvas.save(); // 保存当前状态
2canvas.translate(100, 100);
3canvas.rotate(45); // 先平移再旋转
4paint.setColor(Color.RED);
5canvas.drawRect(0, 0, 50, 50, paint);
6canvas.restore(); // 恢复到保存的状态
完整的自定义控件示例
现在,让我们创建一个简单的自定义控件,展示如何在一个View中使用上述的Canvas
变换和操作。
Java
1public class TransformView extends View {
2 private Paint mPaint;
3
4 public TransformView(Context context) {
5 super(context);
6 init();
7 }
8
9 public TransformView(Context context, @Nullable AttributeSet attrs) {
10 super(context, attrs);
11 init();
12 }
13
14 private void init() {
15 mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
16 }
17
18 @Override
19 protected void onDraw(Canvas canvas) {
20 super.onDraw(canvas);
21
22 // 平移
23 canvas.save();
24 canvas.translate(100, 100);
25 mPaint.setColor(Color.BLUE);
26 canvas.drawRect(0, 0, 50, 50, mPaint);
27 canvas.restore();
28
29 // 缩放
30 canvas.save();
31 canvas.translate(200, 100);
32 canvas.scale(2, 2);
33 mPaint.setColor(Color.GREEN);
34 canvas.drawRect(0, 0, 50, 50, mPaint);
35 canvas.restore();
36
37 // 旋转
38 canvas.save();
39 canvas.translate(300, 100);
40 canvas.rotate(45);
41 mPaint.setColor(Color.YELLOW);
42 canvas.drawRect(0, 0, 50, 50, mPaint);
43 canvas.restore();
44
45 // 剪切
46 canvas.save();
47 canvas.translate(400, 100);
48 canvas.clipRect(0, 0, 100, 100);
49 mPaint.setColor(Color.CYAN);
50 canvas.drawRect(0, 0, 200, 200, mPaint);
51 canvas.restore();
52
53 // 路径绘制
54 canvas.save();
55 canvas.translate(50, 200);
56 Path path = new Path();
57 path.moveTo(0, 0);
58 path.lineTo(50, 50);
59 path.lineTo(100, 0);
60 path.close();
61 mPaint.setColor(Color.MAGENTA);
62 canvas.drawPath(path, mPaint);
63 canvas.restore();
64 }
65}
在这个自定义控件中,我们使用了Canvas
的各种变换和操作来绘制不同效果的图形,展示了Canvas
强大的绘图能力和灵活性。通过这种方式,你可以创建出非常复杂且动态的用户界面组件。