Jetpack Compose 中除了 Canvas
可组合项之外,Compose 还有三个可用于图形绘制的 Modifier/修饰符:drawBehind
, drawWithContent
, drawWithCache
,它们可以应用于任何可组合项。
在本文中,我们将介绍 Jetpack Compose 中的 drawBehind
, drawWithContent
, drawWithCache
的区别和用法。
drawWithContent
drawWithContent
是绘图的基本修饰符,可以在其中决定绘图顺序。
通过修改在
drawWithContent
中调用drawContent
的调用位置实现绘图时可组合项的内容的绘制顺序。
例如,在包含一个 Text
的 Box
可组合项前面绘制半透明的蓝色遮罩层:
@Composable
fun DrawWithContentSample() {
Box(
modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.Center,
) {
Column(
modifier = Modifier
.drawWithContent {
drawContent() // 先调用 drawContent() 则先绘制可组合项的内容
drawRoundRect(
color = Color.Blue,
alpha = 0.6f,
cornerRadius = CornerRadius(16.dp.toPx(), 16.dp.toPx()),
)
}
.padding(16.dp),
) {
Text("Hello itmob.cn")
}
}
}
我们调用了 drawWithContent
方法,它同样接受一个接收者类型为 DrawScope
的 lambda
表达式为参数。
drawBehind
drawBehind
是 drawWithContent
的一个方便使用的封装,它将绘图顺序设置为可组合内容的后面。
例如,通过 drawBehind
为 Text
绘制一个蓝色的圆角背景:
@Composable
fun DrawBehindSample() {
Box(
modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.Center,
) {
Text(
text = "Hello itmob.cn",
modifier = Modifier
.drawBehind {
drawRoundRect(
color = Color.Blue,
cornerRadius = CornerRadius(16.dp.toPx(), 16.dp.toPx()),
)
}
.padding(16.dp),
color = Color.White,
)
}
}
drawBehind
方法拥有一个名为 onDraw,接收者为DrawScope
类型的lambda
表达式,我们在这个lambda
中使用DrawScope
提供的字段和函数进行绘制。
drawWithCache
drawWithCache
可以绘制图形并缓存在其中创建的对象,只要绘图区域的大小相同,或者读取的任何状态对象都没有更改,就会缓存对象。
这个修饰符有助于提高绘图调用的性能,因为它避免了重新分配在绘图时创建的对象(如:
Brush
,Shader
,Path
等)。
注意: 只有在需要创建必须缓存的对象时才使用 Modifier.drawWithCache
,不需要缓存对象时使用此修饰符,可能会导致不必要的lambda分配。
例如,如果通过 Brush
在 Text
后面绘制渐变背景,则可以使用 drawWithCache
来缓存 Brush
”对象,直到绘图区域的大小发生变化:
@Composable
fun DrawWithCacheSample() {
Box(
modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.Center,
) {
Text(
text = "Hello itmob.cn",
color = Color.White,
modifier = Modifier
.drawWithCache {
// 这里创建的对象将被缓存,直到绘图区域发生变化。
val brush = Brush.linearGradient(
listOf(
Color(0xFF9E82F0),
Color(0xFF42A5F5),
),
)
onDrawBehind {
drawRoundRect(
brush = brush,
cornerRadius = CornerRadius(16.dp.toPx()),
)
}
}
.padding(16.dp),
)
}
}
正如上例调用 drawWithCache
修饰符,它接受接收器为 CacheDrawScope
方法,通过 CacheDrawScope
我们可以调用 onDrawBehind
和 onDrawWithContent
来绘制图形。
总结
- 绘图的基本修饰器是
drawWithContent
,在其中可以修改组合项与绘制内容的绘制顺序。 drawBehind
是用于方便调用的drawWithContent
的包装,它的绘图顺序固定为绘制内容在可组合内容的后面。drawWithCache
在其内部调用onDrawBehind
或onDrawWithContent
来绘制,并可以缓存在其中创建的对象。
更多相关文章:
https://developer.android.com/jetpack/compose/graphics/draw/modifiers