https://kotlinlang.org logo
Title
t

Travis Griggs

04/13/2023, 6:06 PM
I have a spacer in a row that is meant to be a separator line. If I define it as:
Spacer(
   modifier = Modifier
      .width(1.dp)
      .height(IntrinsicSize.Max)
      .background(MaterialTheme.colorScheme.outline)
)
it doesn't show up at all. If I change it to
Spacer(
   modifier = Modifier
      .width(1.dp)
      .fillMaxHeight()
      .background(MaterialTheme.colorScheme.outline)
)
Then it shows up, but makes the row be as tall as the screen nearly. How does one achieve the middle ground? I want it to vertically fill the whole row's height, but I don't want it to contribute to how tall the row is, other labels and buttons in the row are doing that already? I have a hunch it's some variation of .layout modifier. But it's not clear how the child node communicates "you can measure my height as big as you're going to be, but really no preference here"
p

Pablichjenkov

04/13/2023, 6:12 PM
I believe there is a matchParentHigh modifier or sort of name. With this exact purpose
t

Travis Griggs

04/13/2023, 6:36 PM
there's a
matchParentSize
in BoxScope, but that's the only match* thing I see
Thanks for the link @ephemient. I've read through like 4 blogs about doing "weird" things with Layout and .layout(), but didn't find that one. It's a bit counterintuitive, in that the primary change is in the Row, rather than the spacer, but it works. I wish that Row/Column could do this uniformly. You can express the placement on the minor axis (e.g. verticalAlignment), but you can't express the vertical fill. In this case, if I want a row/column to be minimally sized to the max content, I have to intrinsic smallest the container, and then specify every child to fillMaxAxis.
p

Pablichjenkov

04/13/2023, 7:24 PM
Humm, only for box? I thought it had this specific purpose. Not sure why is not implemented in row/column, to me is a bit more intuitive than the intrinsic height/width thing. It is like telling the parent, don't measure me, measure other siblings and give me whatever height is determined. But well intrinsic seems to work that way, so is a matter of naming
t

Travis Griggs

04/13/2023, 8:16 PM
I just discovered though that if you have a Row in Column, and you've set the weight of the row to 1f (for the column), and then also add the intrinsic height minimum, your app crashes 😄 So it's not a trick you use ubiquituously apparently
p

Pablichjenkov

04/13/2023, 8:58 PM
Dang, you break it man, congrats lol
e

ephemient

04/13/2023, 8:59 PM
if you try implementing something like
Row { Modifier.matchParentHeight() }
yourself, you'll find that it's doable - if you don't support
Modifier.weight()
. if you do, then measurement can't be done single-pass
p

Pablichjenkov

04/13/2023, 9:07 PM
Humm, 🤔. You mean the same child request for a weight and also matching parent size. Or you mean if another sibling request weight? If is the case of the same child I would say is intuitive if matchParent overrides weight
e

ephemient

04/13/2023, 9:08 PM
they apply in different directions but you can't measure on one axis only
I mean, if you tried implementing it inside Row, not the Row-in-Column thing
p

Pablichjenkov

04/13/2023, 9:30 PM
Ahh right, both axes have to be measured I guess. But it is still under one layout pass. Didn't run your code but it seems to work.
l

Loney Chou

04/13/2023, 10:26 PM
The problem is,
weight
requires all the other children been measured, and
matchParentCrossAxisSize
also requires that, but they're on the different axes, so if there were a child with
weight
and another with
matchParentCrossAxisSize
, it's a deadlock.
BUT! There's something we may be able to do, which is to forbid their combination, but allow one of them at the same time.
e

ephemient

04/13/2023, 10:36 PM
the code I posted only supports
Row { Modifier.matchParentHeight() }
, but not
Modifier.weight()
. I think you'd need separate scope types, and it would be kind of difficult to disambiguate by overload so you'd want separate layout names as well, but haven't thought through it
l

Loney Chou

04/13/2023, 10:37 PM
I'm just brainstorming 😄
One exception. They can be used at the same time only when they both exist on the same child, and exactly one child does that. Maybe just completely saying no to combination is easier, since I think it's quite rare.
p

Pablichjenkov

04/13/2023, 11:16 PM
Selecting one modifier over the other could be an alternative but that would bring another concept, 'modifier priority' which people already get bothered because the applying order matters
e

ephemient

04/13/2023, 11:17 PM
it is not a matter of which modifier has priority
even if there were a
Row { Modifier.matchParentHeight() }
,
Row {
    Box(Modifier.weight(1f))
    Box(Modifier.matchParentHeight())
}
could not be implemented in one layout pass
p

Pablichjenkov

04/13/2023, 11:18 PM
Got you
Although in this type of situation the parent Row could throw warning/exception indicating the problem. NoOneChildSpecifyHeightException or height 0
e

ephemient

04/13/2023, 11:23 PM
it's broken even if there are other children
p

Pablichjenkov

04/13/2023, 11:24 PM
Ahhh, even if at least one specifies a desired height, well 🤷🏻. Yeah complicated to measure everything in one pass.