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 实现,更具声明式风格:

  • 基本绘制:使用 drawRectdrawCircle 等方法。
  • 示例(绘制矩形和文本):
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,请告诉我!

类似文章

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注