drawWithCache
Common
Modifier in Compose Ui
Draw into a [DrawScope] with content that is persisted across draw calls as long as the size of the drawing area is the same or any state objects that are read have not changed. In the event that the drawing area changes, or the underlying state values that are being read change, this method is invoked again to recreate objects to be used during drawing
For example, a [androidx.compose.ui.graphics.LinearGradient] that is to occupy the full bounds of the drawing area can be created once the size has been defined and referenced for subsequent draw calls without having to re-allocate.
Last updated:
Installation
dependencies {
implementation("androidx.compose.ui:ui:1.8.0-alpha04")
}
Overloads
fun Modifier.drawWithCache(onBuildDrawCache: CacheDrawScope.() -> DrawResult)
Code Examples
DrawWithCacheModifierSample
/**
* Sample showing how to leverage [Modifier.drawWithCache] in order to cache contents in between
* draw calls that depend on sizing information. In the example below, the LinearGradient is created
* once and re-used across calls to onDraw. If the size of the drawing area changes, then the
* LinearGradient is re-created with the updated width and height.
*/
@Composable
fun DrawWithCacheModifierSample() {
Box(
Modifier.drawWithCache {
val gradient =
Brush.linearGradient(
colors = listOf(Color.Red, Color.Blue),
start = Offset.Zero,
end = Offset(size.width, size.height)
)
onDrawBehind { drawRect(gradient) }
}
)
}
DrawWithCacheModifierStateParameterSample
/**
* Sample showing how to leverage [Modifier.drawWithCache] to persist data across draw calls. In the
* example below, the linear gradient will be re-created if either the size of the drawing area
* changes, or the toggle flag represented by a mutable state object changes. Otherwise the same
* linear gradient instance is re-used for each call to drawRect.
*/
@Composable
fun DrawWithCacheModifierStateParameterSample() {
val colors1 = listOf(Color.Red, Color.Blue)
val colors2 = listOf(Color.Yellow, Color.Green)
var toggle by remember { mutableStateOf(true) }
Box(
Modifier.clickable { toggle = !toggle }
.drawWithCache {
val gradient =
Brush.linearGradient(
colors = if (toggle) colors1 else colors2,
start = Offset.Zero,
end = Offset(size.width, size.height)
)
onDrawBehind { drawRect(gradient) }
}
)
}
DrawWithCacheContentSample
/**
* Sample showing how to leverage [Modifier.drawWithCache] to cache a LinearGradient if the size is
* unchanged. Additionally this sample illustrates how to re-arrange drawing order using
* [ContentDrawScope.drawContent] in order to draw the desired content first to support blending
* against the sample vector graphic of a triangle
*/
@Composable
fun DrawWithCacheContentSample() {
val vectorPainter =
rememberVectorPainter(24.dp, 24.dp, autoMirror = true) { viewportWidth, viewportHeight ->
Path(
pathData =
PathData {
lineTo(viewportWidth, 0f)
lineTo(0f, viewportHeight)
close()
},
fill = SolidColor(Color.Black)
)
}
Image(
painter = vectorPainter,
contentDescription = null,
modifier =
Modifier.requiredSize(120.dp).drawWithCache {
val gradient =
Brush.linearGradient(
colors = listOf(Color.Red, Color.Blue),
start = Offset.Zero,
end = Offset(0f, size.height)
)
onDrawWithContent {
drawContent()
drawRect(gradient, blendMode = BlendMode.Plus)
}
}
)
}