Canvas.withSave {}

概述

Canvas.withSave {}Kotlin 的一个扩展函数,它允许我们在绘制过程中临时保存和恢复 Canvas 的状态。通过 withSave,我们可以避免手动调用 save()restore(),从而简化代码并减少错误

Canvas.save()Canvas.restore()

  • save():保存当前 Canvas 的状态(如变换矩阵、裁剪区域等)
  • restore():恢复到最近一次 save() 的状态

withSave {}的作用

withSave {} 是一个 Kotlin 扩展函数,它会在 lambda 表达式执行前自动调用 save(),在 lambda 表达式执行后自动调用 restore()。这样可以确保 Canvas 的状态在绘制完成后恢复到原始状态

public inline fun Canvas.withSave(block: Canvas.() -> Unit) {
    val checkpoint = save()
    try {
        block()
    } finally {
        restoreToCount(checkpoint)
    }
}

使用场景

  • 绘制多个图形时:每个图形可能需要不同的变换(如平移、旋转、缩放),使用 withSave{} 可以确保每个图形的变换不会影响其他图形
  • 裁剪区域时:临时裁剪 Canvas 的区域,绘制完成后恢复原始区域
  • 组合绘制操作时:在复杂的绘制逻辑中,确保 Canvas 的状态不会混乱

Demo代码

XML文件(res/layout/activity_main.xml)

<?xml version="1.0" encoding="utf-8"?>
<com.example.myapplication.MyView 
	xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

自定义 View

class MyView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {


    private val paint = Paint().apply {
        color = Color.RED
        style = Paint.Style.FILL
        isAntiAlias = true
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)

        // 绘制背景
        canvas.drawColor(Color.WHITE)

        // 使用 withSave 绘制第一个矩形
        canvas.withSave {
            // 平移并旋转 Canvas
            canvas.translate(500f, 500f)
            canvas.rotate(0f)
            // 绘制矩形
            canvas.drawRect(0f, 0f, 500f, 500f, paint)
        }

        // 使用 withSave 绘制第二个矩形
        canvas.withSave {
            // 修改画笔颜色
            paint.color = Color.BLUE
            // 平移并旋转 Canvas
            canvas.translate(0f, 0f)
            canvas.rotate(45f)
            // 绘制矩形
            canvas.drawRect(0f, 0f, 500f, 500f, paint)
        }
    }
}

运行效果

  • 第一个矩形为红色,位于 (500, 500) 位置
  • 第二个矩形为蓝色,位于 (0, 0) 位置,并旋转了 45
    在这里插入图片描述

总结

  • 核心作用
    withSave {} 通过 自动保存和恢复 Canvas 状态,避免手动调用 save()restore(),减少代码错误
  • 适用场景
    • 多次变换 Canvas(平移、旋转、缩放)
    • 临时裁剪绘制区域
    • 组合复杂绘制操作
  • 性能建议
    • 虽然 withSave 会创建临时作用域,但性能开销可忽略。在嵌套绘制时,建议控制层级深度
Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐