Garret Yoder
03/07/2024, 8:46 PMAlex Vanyo
03/07/2024, 8:50 PMGarret Yoder
03/07/2024, 8:55 PMGarret Yoder
03/07/2024, 8:56 PMPablichjenkov
03/07/2024, 9:01 PMGarret Yoder
03/07/2024, 9:01 PMPablichjenkov
03/07/2024, 9:02 PMGarret Yoder
03/07/2024, 9:02 PMGarret Yoder
03/07/2024, 9:03 PMGarret Yoder
03/07/2024, 9:04 PMPablichjenkov
03/07/2024, 9:05 PMPablichjenkov
03/07/2024, 9:07 PMGarret Yoder
03/07/2024, 9:08 PMPablichjenkov
03/07/2024, 9:09 PMAlex Vanyo
03/07/2024, 9:10 PMAlex Vanyo
03/07/2024, 9:12 PMPablichjenkov
03/07/2024, 9:12 PMPablichjenkov
03/07/2024, 9:13 PMGarret Yoder
03/07/2024, 9:14 PMPablichjenkov
03/07/2024, 9:14 PMAlex Vanyo
03/07/2024, 9:16 PMThat is right, what about if having only 1 component like this in the whole hierarchy? Still scary?What you might see as you resize the window is alternating blank frames and frames with content, or the content will lag behind the window resizing - neither of which is great.
Garret Yoder
03/07/2024, 9:18 PMAlex Vanyo
03/07/2024, 9:20 PMHowever, in some cases I would say I don’t want the screen/window size but just the available constraints size my parent Composable is passing down.Right, in those cases the window size wouldn’t work, and you might need to use
BoxWithConstraints
if the content you want in composition changes due to the available size.
There’s a couple of ways to avoid BoxWithConstraints
though - if you keep the same set of things composed, but just laid out differently, you might be able to use a custom layout, and if you are just hiding a piece of content if there isn’t enough space, you can skip placing a piece of content in your custom layout.Garret Yoder
03/07/2024, 9:22 PMListDetailPaneScaffold
comes to multiplatform since that will solve my use case for needing to care what the window size is anyway.Garret Yoder
03/07/2024, 9:23 PMAlex Vanyo
03/07/2024, 9:24 PMhopefully eventuallyThat makes me very happy to hear 😄comes to multiplatform since that will solve my use case for needing to care what the window size is anyway.ListDetailPaneScaffold
Garret Yoder
03/07/2024, 9:27 PMAlexander Maryanovsky
03/07/2024, 10:50 PMLocalWindowInfo.current.containerSize
help?Alex Vanyo
03/07/2024, 11:02 PMAlexander Maryanovsky
03/07/2024, 11:03 PMAlexander Maryanovsky
03/07/2024, 11:04 PMAlexander Maryanovsky
03/07/2024, 11:09 PMGarret Yoder
03/08/2024, 2:45 AMLocalWindowInfo.current.containerSize
help?
Don't be sorry at all, all input is appreciated!
This looks great and it does work, is there a way to make a derivedstate out of this - or is it just a calculated value and theres no state behind it? It's a composable function so it obviously throws an error. Using it directly would still trigger a recomposition every time the value rolls over, but if theres a way to derivedstate that then I can bucket it in the state and the UI will only do a full recompose any time one of those buckets changesAlexander Maryanovsky
03/08/2024, 12:57 PMval windowInfo = LocalWindowInfo.current
val windowSizeBucket by remember(windowInfo) {
derivedStateOf {
bucketOf(windowInfo.containerSize)
}
}
CompositionLocalProvider(LocalWindowSizeBucket provides windowSizeBucket) {
content()
}
Pablichjenkov
03/08/2024, 2:09 PMbucketOf
seems that it just does the State encapsulation I mentioned.Garret Yoder
03/08/2024, 3:41 PMAlexander Maryanovsky
03/08/2024, 3:45 PMbucketOf
is a method you would write to map a raw size to a bucketAlexander Maryanovsky
03/08/2024, 3:46 PMGarret Yoder
03/08/2024, 3:47 PMGarret Yoder
03/08/2024, 4:04 PMval LocalWindowSizeBucket = compositionLocalOf { AdaptiveLayout.WINDOW_SIZE.MEDIUM }
val windowInfo = LocalWindowInfo.current
val density = LocalDensity.current
val windowSizeBucket by remember(windowInfo) {
derivedStateOf {
AdaptiveLayout.WINDOW_SIZE.getSize(windowInfo.containerSize.width pxToDpWith density)
}
}
CompositionLocalProvider(LocalWindowSizeBucket provides windowSizeBucket) {
}
That works perfectly, and I learned a useful trick. Thanks again guys.Pablichjenkov
03/08/2024, 4:06 PMAlexander Maryanovsky
03/08/2024, 4:07 PMGarret Yoder
03/08/2024, 4:19 PMGarret Yoder
03/08/2024, 4:31 PMval density = LocalDensity.current
val densityInfo = remember { density }
causes the density calc to only be run once so now I'm down to only one recompose when the layout changes, cool!Alexander Maryanovsky
03/08/2024, 4:38 PMval density = LocalDensity.current
val densityInfo = remember { density }No. Not sure what you’re trying to do here. I meant that it should be
val windowSizeBucket by remember(windowInfo, density) { ... }
but actually that’s not critical. If density changes the derived state calculation will notice it anyway.Alexander Maryanovsky
03/08/2024, 4:40 PMval density = LocalDensity.current
val densityInfo = remember { density }This will not work well if density changes, because you’re caching it unconditionally.
Garret Yoder
03/08/2024, 4:40 PMGarret Yoder
03/08/2024, 4:43 PMAlexander Maryanovsky
03/08/2024, 5:03 PMderivedStateOf
captures the value of density
when it’s created. When the density changes the lambda won’t be recreated, so it will continue using the old value.Alexander Maryanovsky
03/08/2024, 5:03 PMGarret Yoder
03/08/2024, 5:45 PMval LocalWindowSizeBucket = compositionLocalOf { AdaptiveLayout.WINDOW_SIZE.MEDIUM }
val density = LocalDensity.current
val windowInfo = LocalWindowInfo.current
val windowSizeBucket by remember(windowInfo, density) { derivedStateOf { AdaptiveLayout.WINDOW_SIZE.getSize(windowInfo.containerSize.width pxToDpWith density) } }
println(windowSizeBucket)
CompositionLocalProvider(LocalWindowSizeBucket provides windowSizeBucket) {
windowSizeBucket outside of the compositionlocal is properly changing
Edit: I found why, the compositionLocalOf needs to be wrapped in a remember.Alexander Maryanovsky
03/08/2024, 8:14 PMAlexander Maryanovsky
03/08/2024, 8:14 PMAlexander Maryanovsky
03/08/2024, 8:15 PMAlexander Maryanovsky
03/08/2024, 8:15 PMAlexander Maryanovsky
03/08/2024, 8:17 PMval LocalWindowSizeBucket = compositionLocalOf { AdaptiveLayout.WINDOW_SIZE.MEDIUM }
This needs to be a global valGarret Yoder
03/08/2024, 8:33 PM