Hi! Did anyone tried and failed to create a proper...
# compose
t
Hi! Did anyone tried and failed to create a proper FlexBox implementation in Compose or is it just a niche layout waiting for its hero to implement it? The whole purpose of this question is to research any known compatability issues between flexbox and Compose single-pass layout model before trying to implement it myself
f
Closest to Flexbox is probably FlowLayout in Accompanist
c
I’m not sure a “proper flexbox” layout is needed. All of the standard layouts (column, row, box) use alignment/arrangement attributes that are the same offered by Flexbox. And with FlowLayout as mentioned above, you’ve really got all the flexibility you need in layouts, and they’re more standard and easier to use than trying to recreate FlexBox layouts
Granted, it’s been a while since I’ve used FlexBox or HTML/CSS layouts, but in my experience I always struggled to get things aligned properly, even with FlexBox, but have never really had any struggles understanding or working with Compose’s layout system
t
I know about FlowLayout, but it is not following the spec. For example, it doesn't have shrink. The thing is that we have a large part of the app written using YogaLayout, which is essentially a crossplatform flexbox implementation. I can't rewrite everything to using rows/columns so I wondered if there is a possibility to write own flexbox
c
I’m sure it could be done, but I don’t think I’ve ever heard of anyone trying it yet. The Compose
Layout { }
API is pretty expressive yet simple to work with, though a full FlexBox implementation would be anything by trivial. Here’s the docs on basic custom layouts if you’d like to give it a try yourself: https://developer.android.com/jetpack/compose/layouts/custom
f
Or you could look at how
FlowLayout
is implemented and iterate from that
t
My main concern was that FlexLayout was once deprecated and replaced by FlowLayout. That makes me wonder if there are some difficulties in implementing flex even compose devs could not overcome
f
If I remember correctly it was just because there was not enough time to maintain and stabilise that API to 1.0 release so they minimised the API available in 1.0 to focus on that. That does not mean that there is no blocker in implementing full FlexBox layout tho. If you are really trying to do this, there is one trick to partially sidestep the single-pass requirement in Compose - SubcomposeLayout. It enables you to influence one part of your layout with measure result from other part. Look at Scaffold for a
SubcomposeLayout
example.
s
This isn’t quite it, but I’ve seen there’s been some work on redwood regarding flexbox, which is used by redwood-layout which I then assume will in the future be used in the common UI declarations and will eventually be used from the ComposeUI side too. So (again, a guess, I don’t quite understand what’s happening in redwood) maybe there’s gonna be some development over there regarding this, but nothing is there atm as far as I can see from glancing at the code at least.
t
@Stylianos Gakis thanks for the link, i'll glance at it
s
Yeah as far as I understand, at its current state this is far from what you’re looking for, so I don’t want to get your hopes up unnecessarily 😅
z
SubcomposeLayout … enables you to influence one part of your layout with measure result from other part.
Sorry to be pedantic here, but this is a mistake a lot of people make so I wanted to call it out. Different parts of a layout can influence other parts of the layout in a normal
Layout
, you don’t need subcomposition for that and shouldn’t use it to do so because it is relatively expensive and inefficient.
SubcomposeLayout
allows the layout (measure or placement) to influence the composition of other children of that layout. That is needed in many fewer cases. Eg I believe Scaffold uses this capability to completely avoid composing whole complicated parts of itself when certain params are null.
s
A thread I read recently that explained this quite well imo https://twitter.com/halilozercan/status/1575594603587465216 for those interested
t
@Zach Klippenstein (he/him) [MOD] thanks for the clarification. Do you how to remeasure children inside Layout without using SubcomposeLayout? I got YogaLayout engine to work, but it needs to remeasure children using different size constrains to operate. Can i do this kind of (obviously poor for perfomance but necessary to work with yoga) thing in Layout node?
z
Compose’s layout system forbids measuring something more than once in a single pass, because it’s bad for performance. You can technically do it with SubcomposeLayout, but that’s even worse for performance because you’re not only measuring something multiple times, you’re composing it multiple times, which is even more expensive.
t
Yeah I know about this restriction, but maybe there is some "use for your own risk" workaround for that?
z
Nope
s
Just realized this is public, a colleague of mine has been playing around in this repo to do something like that. Why don’t you take a peak and see if this helps you? I haven’t seen nor touched the code in there so I don’t have any opinions/help to provide to you regarding it.
t
Oh, cool link! I'll take a look at it, thanks
@Zach Klippenstein (he/him) [MOD] FYI it seems like there is in fact an api for measuring multiple times (but it is unstable)
MultiMeasureLayout
z
It’s commented as a temporary thing to allow constrainlayout prototyping. That sounds like less than experimental - i wouldn’t build anything serious on it.
b
If it helps anyone that lands here, I ported YogaLayout (A C++ library implementing Flexbox) to pure Kotlin so it can be used in multiplatform: https://github.com/Joingo/yoga-kotlin It doesn't include a Composable wrapper but it's one step closer (I don't need a Composable in my use case, I just pass the x/y/width/height directly to Modifiers)
t
I did a composable wrapper around yoga. It even supports virtualizing nested layouts. We've going to opensource it Q1 2023
b
@themishkun Cool, I'd love to use that if Compose iOS & WASM reach maturity! I'm still using different UI's per platform (Compose Android, HTML for web, SwiftUI iOS) but needed to some layout in
commonMain
, so that's why I did not make a Composable yet. Feel free to use my fork if you'd like to support Desktop/iOS/WASM as well. It even includes all the unit tests (passing!) from upstream Yoga (If there's interest I can put it on maven central and get CI going, etc.)