Canvas API详解(Part 1)
Canvas API 详解 (Part 1)
在 Android 的绘图系统中,Canvas
类是核心组件,用于执行绘制操作。它与 Bitmap
(存储像素)、绘制图元(如矩形、路径、文本、位图)和 Paint
(定义颜色和样式)结合,实现 2D 图形渲染。Canvas
常用于自定义 View 或 SurfaceView 中的图形绘制,是 Android 图形系统的基石。本部分(Part 1)重点介绍 Canvas
的基础概念、构造函数和基本绘制方法(绘制图元)。后续部分将深入变换、裁剪和状态管理等高级主题。
Canvas 的作用与应用场景
- 作用:
Canvas
持有绘制调用,提供方法绘制形状、文本和位图,支持矩阵变换、裁剪和状态保存。它本质上是绘图操作的“画布”,所有绘制都受当前矩阵、裁剪区域和Paint
影响。 - 应用场景:
- 自定义 View 的
onDraw
方法中绘制 UI 元素。 - 游戏或动画渲染(如 SurfaceView)。
- 生成位图(如动态图标或缓存图形)。
- 结合
Paint
实现复杂效果(如渐变填充或路径效果)。
要使用 Canvas
,通常在 View.onDraw(Canvas canvas)
中获取系统提供的实例,或手动创建绑定到 Bitmap
。
构造函数
Canvas
提供两种主要构造函数,用于初始化画布:
构造函数 | 描述 | 参数示例 | 用法示例 |
---|---|---|---|
Canvas() | 创建一个空的光栅画布,后续需调用 setBitmap() 指定位图。初始密度为 Bitmap.DENSITY_NONE 。 | 无参数 | Canvas canvas = new Canvas(); canvas.setBitmap(bitmap); |
Canvas(Bitmap bitmap) | 创建画布并绑定到指定的可变位图,继承位图的密度。位图必须是可变的。 | bitmap (Bitmap,非空且可变) | Canvas canvas = new Canvas(mutableBitmap); |
- 注意:绑定位图后,所有绘制操作都会直接修改该位图。未绑定位图的画布无法绘制。
基本绘制方法(绘制图元)
Canvas
提供了多种方法绘制基本图形、文本和位图。这些方法通常需要 Paint
对象定义样式(如颜色、粗细)。以下是关键方法及其用法:
方法名称 | 描述 | 主要参数 | 用法示例 |
---|---|---|---|
drawColor(int color) | 用指定颜色填充整个画布(当前裁剪区域内),使用 SRC_OVER 模式。 | color (int,颜色值) | canvas.drawColor(Color.RED); |
drawRect(float left, float top, float right, float bottom, Paint paint) | 绘制矩形,使用给定的 Paint 定义样式。 | left, top, right, bottom (float,矩形边界);paint (Paint,非空) | canvas.drawRect(0, 0, 100, 100, paint); |
drawCircle(float cx, float cy, float radius, Paint paint) | 绘制圆形,中心在 (cx, cy),半径为 radius。 | cx, cy (float,中心坐标);radius (float);paint (Paint,非空) | canvas.drawCircle(50, 50, 30, paint); |
drawLine(float startX, float startY, float stopX, float stopY, Paint paint) | 绘制线段,从起点到终点。 | startX, startY, stopX, stopY (float,端点坐标);paint (Paint,非空) | canvas.drawLine(0, 0, 100, 100, paint); |
drawPath(Path path, Paint paint) | 绘制自定义路径(Path 对象定义的形状)。 | path (Path,非空);paint (Paint,非空) | Path path = new Path(); path.lineTo(100, 100); canvas.drawPath(path, paint); |
drawText(String text, float x, float y, Paint paint) | 在 (x, y) 位置绘制文本,位置根据 Paint 的 Align 设置解释。 | text (String,非空);x, y (float,位置);paint (Paint,非空) | canvas.drawText("Hello", 10, 50, paint); |
drawBitmap(Bitmap bitmap, float left, float top, Paint paint) | 在 (left, top) 位置绘制位图,受当前矩阵变换影响,支持密度缩放。 | bitmap (Bitmap,非空);left, top (float,位置);paint (Paint,可空) | canvas.drawBitmap(bitmap, 0, 0, paint); |
这些方法是绘制的基础,受当前变换矩阵和裁剪区域影响。结合 Paint
的效果(如 Shader 或 PathEffect),可实现渐变、虚线等高级渲染。
代码示例
以下是一个自定义 View 示例,演示基本绘制方法的使用。复制到 Android 项目中运行,即可在画布上看到各种图元。
import android.content.Context;
import android.graphics.*;
import android.util.AttributeSet;
import android.view.View;
public class CanvasBasicsView extends View {
private Paint paint;
public CanvasBasicsView(Context context, AttributeSet attrs) {
super(context, attrs);
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.BLACK);
paint.setStrokeWidth(5f);
paint.setTextSize(40f);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 1. 填充颜色
canvas.drawColor(Color.LTGRAY);
// 2. 绘制矩形
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.RED);
canvas.drawRect(50, 50, 150, 150, paint);
// 3. 绘制圆形
paint.setColor(Color.BLUE);
canvas.drawCircle(100, 250, 50, paint);
// 4. 绘制线段
paint.setStyle(Paint.Style.STROKE);
paint.setColor(Color.GREEN);
canvas.drawLine(50, 350, 150, 450, paint);
// 5. 绘制路径
Path path = new Path();
path.moveTo(50, 500);
path.lineTo(100, 550);
path.lineTo(50, 600);
paint.setColor(Color.YELLOW);
canvas.drawPath(path, paint);
// 6. 绘制文本
paint.setColor(Color.BLACK);
canvas.drawText("Hello Canvas", 50, 700, paint);
// 7. 绘制位图(需准备位图)
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher_foreground); // 替换为你的资源
canvas.drawBitmap(bitmap, 50, 750, null);
}
}
- 运行效果:画布上从上到下显示灰色背景、红色矩形、蓝色圆形、绿色线段、黄色路径、黑色文本和位图。
- 扩展:结合
Paint
的 Typeface 或 Shader,可实现自定义字体或渐变填充的文本/形状。
注意事项
- 性能:频繁绘制复杂图元可能影响性能,建议使用
Bitmap
缓存静态内容。 - 兼容性:
Canvas
自 API 1 起支持,默认启用硬件加速(API 14+),但某些效果(如 ShadowLayer)需切换到软件渲染。 - 坐标系:默认左上角为 (0,0),向右下递增。所有绘制受当前矩阵影响。
- 调试:在自定义 View 中重写
onDraw
,使用 Log 或 Visual Inspector 检查渲染结果。 - 与 Paint 的结合:
Canvas
负责“绘制什么”,Paint
负责“怎么绘制”。例如,用paint.setShader(new LinearGradient(...))
实现渐变矩形。
扩展:Jetpack Compose 中的等效实现
在 Jetpack Compose 中,Canvas
的功能通过 Canvas
组件和 DrawScope
实现,更具声明式风格:
- 基本绘制:使用
drawRect
、drawCircle
等方法。 - 示例(绘制矩形和文本):
import androidx.compose.foundation.Canvas
import androidx.compose.runtime.Composable
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
@Composable
fun BasicCanvas() {
Canvas(modifier = Modifier.size(200.dp)) {
drawRect(
color = Color.Red,
topLeft = Offset(50f, 50f),
size = Size(100f, 100f)
)
drawCircle(color = Color.Blue, center = Offset(100f, 250f), radius = 50f)
drawText(...) // 需要额外导入 androidx.compose.ui.text.drawText
}
}
- 说明:Compose 的
Canvas
更简洁,支持 Modifier 调整大小和位置。复杂路径用drawPath
。
本部分聚焦基础绘制,Part 2 将覆盖变换(translate/scale 等)、裁剪(clipRect/clipPath)和状态管理(save/restore)。如果需要特定方法的深入示例、动画集成,或直接跳转到 Part 2,请告诉我!