https://kotlinlang.org logo
#compose
Title
# compose
m

mattinger

03/08/2022, 3:36 PM
So i’m working with a layout that is drawing a custom progress ring animation. I’m having trouble figuring out how to give it an intrinsic size so that until a specific size is give, or it’s give a fillMaxWidth/FillMaxSize, it will use that size:
Copy code
BoxWithConstraints(
        modifier = modifier
            .defaultMinSize(RingDefaultMinSize, RingDefaultMinSize)
            .aspectRatio(RingAspectRatio)
            .padding(RingStrokeWidthOffset),
        contentAlignment = Alignment.Center
    ) {
        Canvas(modifier = Modifier.size(constraints.maxWidth.dp, constraints.maxHeight.dp)) {
            drawArc(
                color = ringColor,
                startAngle = rotation.value,
                sweepAngle = -1f * sweepAngle.value,
                useCenter = false,
                style = Stroke(width = RingStrokeWidth.toPx(), cap = StrokeCap.Round)
            )
        }
    }
The problem is that when i don’t specify any size, the Box is filling it’s entire parent. I know it’s due to my use of contraints.maxWidth, but i’m unsure how to properly figure out the size of the canvas based on the constraints.
z

Zach Klippenstein (he/him) [MOD]

03/08/2022, 4:03 PM
I think you want to use
Modifier.size
as well as
defaultMinSize
, which will effectively set the “default” size, which can be overruled by incoming constraints. I'm not sure if either of those will publish intrinsics though, you might need a
layout
modifier to do that. But you definitely don't need
BoxWithConstraints
for this.
m

mattinger

03/08/2022, 4:24 PM
@Zach Klippenstein (he/him) [MOD] as it turns out, i looked at CircularProgressIndicator, and setting the size and just having a canvas works the way i want it to. I had originally based this animation off something else which had a BoxWithConstraints.
But this works fine:
Copy code
Canvas(
        modifier = modifier
            .padding(RingStrokeWidthOffset)
            .size(RingDefaultMinSize, RingDefaultMinSize)
            .aspectRatio(RingAspectRatio)
    ) {
        drawArc(
            color = ringColor,
            startAngle = rotation.value,
            sweepAngle = -1f * sweepAngle.value,
            useCenter = false,
            style = Stroke(width = RingStrokeWidth.toPx(), cap = StrokeCap.Round)
        )
    }
and if i pass in a modifier with a size() or fillMaxSize() it expands out appropriately.
@Zach Klippenstein (he/him) [MOD] The downside to this is that that if you nest this in a box, and pass a fillMaxSize modifier to it, it actually expands the parent box to fill the entire screen, rather than the box just expanding to fill the larger of the two children, and then the canvas matching that size. That said, i get the same behavior with CircularProgressIndicator, so it’s not entirely unexpected.
c

Chris Sinco [G]

03/08/2022, 8:56 PM
s it turns out, i looked at CircularProgressIndicator, and setting the size and just having a canvas works the way i want it to.
Yes, Canvas has a size variable in the drawScope that you should use to base measurements on (which is based on the constraints passed down to it)