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 不参与布局,改占位要动布局。