Hi! I've noticed that `Modifier.progressSemantics`...
# compose
v
Hi! I've noticed that
Modifier.progressSemantics
causes recompositions. I've a custom
ProgressIndicator
, and if I use
Modifier.progressSemantics
Android Studio "Layout inspector" shows thousand recompositions. Is it a bug of "Layout inspector", or it is normal?
Every tick of a progress counts as a recomposition. This is with
Modifier.progressSemantics
t
I think we'd have to see the code of
SegmentedProgressIndicator
to know what the ultimate cause is. But you might try replacing that with an indeterminate
CircularProgressIndicator
just to see if that also recomposes every frame.
a
It's normal because
Modifier.progressSemantics
reads the value in the current recomposition scope. This usually shouldn't be a problem because when you draw a progress bar you likely need it to be recomposed anyway. If you want to reduce recomposition, you can use
Modifier.semantics(mergeDescendants = true) { progressBarRangeInfo = ... }
(see the source of
Modifier.progressSemantics
).
v
The source code for the
SegmentedProgressIndicator
is taken from this article. Only code is in this gist.
The only diffrence in my verstion is that I've replaced
Copy code
progress: Float
with
Copy code
progressProvider: () -> Float
If I use what @Albert Chang suggested it works without additional recompositions. So thank you!
Copy code
@Composable
fun SegmentedProgressIndicator(
    progressProvider: () -> Float,
    numberOfSegments: Int,
    modifier: Modifier = Modifier,
    color: Color = Color.White,
    backgroundColor: Color = color.copy(alpha = BackgroundOpacity),
    progressHeight: Dp = ProgressHeight,
    segmentGap: Dp = SegmentGap
) {
    val gap: Float
    val barHeight: Float
    with(LocalDensity.current) {
        gap = segmentGap.toPx()
        barHeight = progressHeight.toPx()
    }
    Canvas(
        modifier
            .semantics(mergeDescendants = true) {
                progressBarRangeInfo = ProgressBarRangeInfo(progressProvider().coerceIn(0f..1f), 0f..1f, 0)
            }
            .height(progressHeight)
    ) {
        drawSegments(1f, backgroundColor, barHeight, numberOfSegments, gap)
        drawSegments(progressProvider(), color, barHeight, numberOfSegments, gap)
    }
}