How would I go about making sure the circles dont ...
# compose
z
How would I go about making sure the circles dont extend past the text width?
I thought
IntrinsicSize
might help, but no bueno. Current layout is below:
Copy code
Column(
    modifier = Modifier.padding(
        vertical = KeylineSmall,
        horizontal = KeylineMedium,
    ),
    content = {
        Row(
            verticalAlignment = CenterVertically,
            horizontalArrangement = spacedBy(SpaceMedium),
            content = {
                Text(
                    text = label(AllAccounts),
                    style = Theme.type.overline,
                    emphasis = Subtle,
                    variant = Strong,
                )

                repeat(15) { // TODO: Remove
                    portfolio.accounts.forEach { account ->
                        Circle(
                            color = colorize(account.color),
                            size = CircleMini,
                        )
                    }
                }
            },
        )

        Amount(
            value = portfolio.total,
            currencyCode = portfolio.currencyCode,
            size = Large,
        )
    },
)
a
You can measure width of your text, label, and add (text.width-label.width)/(CircleMini+SpaceMedium) circles insted of 15
z
Thanks @Alexander Zhirkevich, I suppose that would work. Ideally I hope theres a simpler solution though? I would need to tinker with my code quite a bit to make that work 😅
a
Consider custom layout instead of a Column. First you measure the Amount child and then using its width the Row
z
Got it. Thank you both!
y
I suspect there is a way to have a parent container with wrapContentWidth. But tell the dotted lines to have a weight of 1 ?
e
Copy code
Column(
  Modifier
    .padding(vertical = 12.dp, horizontal = 16.dp)
    .width(IntrinsicSize.Min)
) {

  Row(
    verticalAlignment = Alignment.CenterVertically,
    horizontalArrangement = Arrangement.spacedBy(8.dp),
  ) {
    Text(
      text = "All accounts",
      style = MaterialTheme.typography.labelSmall,
    )

    Canvas(
      Modifier
        .weight(1f)
        .height(8.dp)
    ) {
      val minDimen = size.minDimension
      val radius = minDimen / 2
      val sectionLen = minDimen + 4.dp.toPx()/*spacing*/
      val count = (size.width / sectionLen).roundToInt()
      repeat(count) { index ->
        drawCircle(
          color = Color.Blue,
          center = Offset(x = (index * sectionLen) + radius, y = radius),
        )
      }
    }
  }

  Text(
    text = money,
    style = MaterialTheme.typography.headlineSmall,
  )
}
Intrinsic size on the Column. Custom drawing using the measured size.
Also a
FlowRow
might be a solution too, since it composes content as far as there is space!
1
z
@yschimke Yes! This is ultimately what Im looking for, but nothing seems to get the job done. @efemoney I can see how canvas would work for that! But my circle is more complicated than drawCircle 😞 I dont think I can replicate all of it with canvas API:s. For me, when using FlowRow the circles just continue on another line (after extending to the full width of the screen).
e
Yeah FlowRow will not work. I just looked at the impl, its basically a row that can go to the next line.
z
Still feel like this should be doable in a "simple way"; not the end of the world if it isnt - but would love to know just for the learnability of it!
y
Copy code
@Composable
@Preview
fun Test() {
    Box(modifier = Modifier.size(400.dp)) {
        Column(modifier = Modifier.width(IntrinsicSize.Min)) {
            Row(modifier = Modifier.fillMaxWidth()) {
                Text(text = "All Accounts", style = MaterialTheme.typography.caption3)
                Box(modifier = Modifier.background(Color.Red).fillMaxWidth().height(10.dp))
            }
            Text(text = "$1,098,397.00", style = MaterialTheme.typography.title1)
        }
    }
}
image.png
e
That works because your Box doesn’t have content thats wants to be a particular size. Replace Box with a row that draws 15 10 x 10 dp boxes
y
BoxWithConstraints for the circle box and just decide how many to draw?
That feels simple
e
You cant use box with constraints (or any other subcompose layouts) with Intrinsic Size
y
Ahhh
z
I dont have the opportunity to test this right now, but wouldnt something like this work? The circles weight would conform to the min intrinsic size; I think?
Copy code
Column {
    Row(Modifier.width(Min)) {
        AllAccounts() + Row(Modifier.weight(1f)) { Circles )
        Amount()
    }
}
🚫 1
e
I’d still recommend custom drawing @Zoltan Demant. If thats not possible then custom
Layout
is the way to go. With custom Layout you will compose all accounts normally but then you can place only those you have space for and more importantly, you will report the correct constrained size back. Its a shame though, because you’d have to reimplement Row measurement & layout in the process.
z
Gotcha 👍🏽 Yeah, creating a custom layout feels daunting for an edge case like this; Ill choose another approach altogether. Still appreciate all the discussion around the subject! 💪🏽
z
If you need the available size to affect what actually gets composed, eg you are repeating some composables, then subcomposition is the only way. So i would first try to get the circle-repeating code out of composition, so you can defer determining how many circles you need until after the layout phase.
👍🏽 1
👍 1