绘制与图层 · AndroidX 源码指南
AAndroidX 源码指南
Compose UI
Compose 底层 · androidx.compose.ui

绘制与图层1.13.0-alpha01

在 drawBehind、drawWithContent、drawWithCache 和 graphicsLayer 之间选择。

最后更新 2026-08-01

复制即用

// drawWithContent:先画内容,再画前景遮罩
Modifier.drawWithContent {
    drawContent()
    drawRect(
        color = Color.Black.copy(alpha = 0.2f),
        blendMode = BlendMode.SrcOver,
    )
}

// drawBehind:在自身内容下面画
Modifier.drawBehind {
    drawCircle(
        color = Color.Red,
        radius = size.minDimension / 2f,
    )
}

// Canvas:无修饰符的独立绘制区域
Canvas(Modifier.fillMaxSize()) {
    drawLine(
        color = Color.Blue,
        start = Offset(0f, 0f),
        end = Offset(size.width, size.height),
        strokeWidth = 4f,
    )
}

四个入口

  • drawBehind:先画自定义内容,再由节点绘制自身内容。
  • drawWithContent:自己决定何时调用 drawContent(),可以画前景、遮罩或完全替换。
  • drawWithCache:按尺寸和读取状态缓存昂贵绘制对象。
  • graphicsLayer:把 alpha、scale、rotation、clip 等变换应用到图层。

缓存什么

Modifier.drawWithCache {
    // 按 size 缓存昂贵的 Brush/Path
    val brush = remember(size) {
        Brush.radialGradient(listOf(Color.Red, Color.Blue), center = center)
    }
    onDrawBehind {
        drawRect(brush)
    }
}

drawWithCache 适合缓存依赖 size、颜色或路径的 Brush/Path 等对象;状态改变或尺寸改变时会重建缓存。一个纯 drawRect(color) 不值得为了”优化”额外加缓存层。

图层不是布局

graphicsLayer { translationX = ... } 改变绘制位置,但不会重新分配父布局空间。兄弟节点仍按原来的布局坐标排列;需要真正改变占位时应修改布局或 offset 策略。

常见陷阱

  • graphicsLayer 当布局用:它只影响绘制,不参与父布局测量。
  • 乱加 drawWithCache:简单绘制加缓存层反而增加复杂度。
  • drawWithContent 忘调 drawContent():内容会消失(除非故意替换)。
  • 高频状态触发重建:drawWithCache 缓存依赖的状态变了会重建,别把高频变化放进去。

要点

  • 四个入口分工:drawBehind 背景、drawWithContent 前景/遮罩、drawWithCache 昂贵对象、graphicsLayer 图层变换。
  • 缓存依赖 size/color/path 的对象;纯色绘制不值得缓存。
  • graphicsLayer 不参与布局,改占位要动布局。

相关页面