I get to bug Googlers on here now :smile: When a `...
# compose
z
I get to bug Googlers on here now šŸ˜„ When a `Row`'s incoming width is unconstrained, is it WAI that it measures its weighted children as 0-width? That makes sense since
Modifier.weight
is intended to distribute "available space", and if the width constraint is infinity, then it can't do that (āˆž / anything = āˆž, and nodes can't have infinite measured width). If so, i'll file a CL to update the documentation.
😭 1
s
Afaik this has been the behavior since forever. And the reason why weight basically does nothing in scrollable lists which make the constraints infinite as you describe. Is there some documentation that describes the opposite, or is it that it's simply not mentioned anywhere? Also, welcome to being a compose consumer rather than builder yet again šŸ˜‚
z
It makes sense from the rules. It feels weird somehow though. Stuff like this make Row hard to use as an implementation for libraries, and makes me even more persuaded that custom layouts are often the best thing. I’m not sure what a more reasonable default would be though. I think a doc update is probably the best thing to do.
s
Yup, tbh this and https://kotlinlang.slack.com/archives/CJLTWPH7S/p1712328544046829?thread_ts=1712320576.946129&cid=CJLTWPH7S are the two things which I've always found hard to accept that they are the way they are on column/rows šŸ˜…
z
I’ve been thinking about making a little library with alternatives to basic stuff like this that are more powerful. Cross-axis constraint propagation, default weight, explicit unspecified weight, proportional measuring, etc. Might try some of these ideas internally and if they actually work, publish them
s
Do it and name them "Column2" and "Row2", you've done it before, I know you can do it again šŸ˜… If that library has one person using it I can absolutely guarantee you that it would be me.
2ļøāƒ£ 3
z
Was thinking
HStack
and
VStack
😜
šŸ‘Œ 1
s
Nooooooooo please no šŸ˜‚
šŸ˜‚ 1
s
HColumn and VRow
z
Copy code
import cursedlayouts.*
😭 3
Joking aside, I want to see if there’s a better way to provide this than composables. Eg maybe just extensible
MeasurePolicy
classes or helper functions. Eg if we had something like this:
Copy code
interface ScopedMeasurePolicy<ContentScopeT> : MeasurePolicy {
  val contentScope: ContentScopeT
}

@Composable
inline fun <ContentScopeT> Layout(
  measurePolicy: ScopedMeasurePolicy<ContentScopeT>,
  modifier: Modifier,
  content: @Composable ContentScopeT.() -> Unit
)
Then we could provide stuff like:
Copy code
open class StackMeasurePolicy(
  val orientation: Orientation,
  val defaultChildWeight: Float = Unspecified,
  …
): ScopedMeasurePolicy<StackScope> {
  override val contentScope get() = StackScope

object StackScope {
  fun Modifier.weight(…): Modifier
  fun Modifier.weightUnspecified(): Modifier
  …
}
But probably with more extension points, injectable logic for certain things, etc. Consumers can then just pass an instance to that layout composable:
Copy code
@Composable
fun MySpecialRow(
  modifier: Modifier = Modifier,
  content: StackScope.() -> Unit
) {
  val measurePolicy = remember {
    StackMeasurePolicy(…)
  }
  Layout(measurePolicy, modifier, content)
}
s
In 100% of the places we use a weight, we basically do:
Copy code
Column {
 Stuff()
 Spacer(weight(1f))
 Spacer(height(8.dp))
 MoreStuff()
}
To fight this. Because the weight can always evaluate to 0.dp and then they touch and basically it never is what we actually want in the places we put the weight in
z
Thinking about this more, I think I’ve convinced myself that using max intrinsic size would be the most reasonable default. If
weight
means ā€œtake a fraction of the available spaceā€, and 0-ā™¾ļø constraints means ā€œbe your natural sizeā€, then the natural ā€œavailableā€ width is the sum of all the children’s max intrinsic widths, because the total width can’t be more than that. I’m mostly convinced this makes sense, but it’s definitely arguable. More importantly however, that’s moot because it’s probably way too late to change this behavior for Row/Column.
I also realized this behavior is documented on Row/Column itself, but not on the
weight
modifier itself. Who would think to look at the weight modifier kdoc for information about weight behavior anyway? šŸ˜ So I’ll still fix this.
@Uchenna Okoye are you still looking for Row/Column ideas?
šŸ¤ž 2
Copy code
@Composable
inline fun LinearLayout(content: @Composable () -> Unit)
🧌
🧌 2