I have a spacer in a row that is meant to be a separator line. If I define it as: ```Spacer( modi...
t
I have a spacer in a row that is meant to be a separator line. If I define it as:
Copy code
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
Copy code
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
I believe there is a matchParentHigh modifier or sort of name. With this exact purpose
t
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
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
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
Dang, you break it man, congrats lol
e
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
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
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
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
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
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
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
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
it is not a matter of which modifier has priority
even if there were a
Row { Modifier.matchParentHeight() }
,
Copy code
Row {
    Box(Modifier.weight(1f))
    Box(Modifier.matchParentHeight())
}
could not be implemented in one layout pass
p
Got you
Although in this type of situation the parent Row could throw warning/exception indicating the problem. NoOneChildSpecifyHeightException or height 0
e
it's broken even if there are other children
p
Ahhh, even if at least one specifies a desired height, well 🤷🏻. Yeah complicated to measure everything in one pass.