https://kotlinlang.org logo
#compose
Title
# compose
s

shikasd

07/23/2020, 10:30 PM
Hey, does compose provide functionality to "attach"/"detach" layout nodes? Basic example is routing: we have a list with some heavy animation running on screen -> open detail of list item on top. In that case it will be great to not draw the background screen anymore but keep scroll state of the list. Currently two solutions I've seen is to either draw screens on top of each other (quite inefficient), or just switch composables completely (doesn't keep the state). Maybe there are some interesting methods of making pieces of composition detached (not drawing them) while keeping the state?
z

Zach Klippenstein (he/him) [MOD]

07/23/2020, 10:38 PM
The background screen should save any state it cares about using the
UiSavedStateRegistry
(ie. using
savedInstanceState
), then you can stop composing it and restore it later.
This is the same idea as classic android views and
onSaveInstanceState
– scroll views save their scroll position here, then when they’re restored, they read it back.
s

shikasd

07/23/2020, 10:41 PM
Huh, makes sense Probably need to check how we can support
UiSavedStateRegistry
in
compose-router
and such, thanks 🙂
z

Zach Klippenstein (he/him) [MOD]

07/23/2020, 10:43 PM
All the standard Android components facilitate this (Activity/Fragment), and any backstack library that wants to play nice with android views needs to support this mechanism too (e.g. https://github.com/square/workflow-kotlin/blob/56dc0762151602006308d451baad97145bdfe91e/workflow-ui/backstack-android/src/main/java/com/squareup/workflow1/ui/backstack/BackStackContainer.kt#L76-L85).
s

shikasd

07/23/2020, 10:45 PM
Yeah, we did it for RIBs quite a long time ago, but I just missed when it was introduced in compose 🙂
On the unrelated note it is quite funny how everyone produces their notion of backstack library, which actually work in quite a similar way ¯\_(ツ)_/¯
Yea, I think every UI developer eventually writes a backstack library 😂
s

shikasd

07/23/2020, 10:48 PM
Don't get me started on MV-whatever libraries 😅 Thanks for references!!
t

Timo Drick

07/23/2020, 11:01 PM
I think it is a good sign when everyone can write their own backstack lib in a few lines of code. Including myself :-)
4
It gets more complicated when we now want to integrate some more advanced transitions between screens. (Morphing one image into the new screen or s.th. like that)
z

Zach Klippenstein (he/him) [MOD]

07/23/2020, 11:07 PM
I have an idea for that using subcomposition i want to play with at some point, where e.g. the image composable actually becomes the new screen so you don’t need any “shared element” stuff
😲 2
t

Timo Drick

07/23/2020, 11:08 PM
sounds great. Interesting idea.
r

romainguy

07/23/2020, 11:11 PM
Note that the rendering pipeline on Android should be able to eliminate the rendering of all the hidden elements automatically
As long as the screen on top has a solid background for instance
💡 1
t

Timo Drick

07/23/2020, 11:14 PM
So instead of switching to a new component we could just change the size of one subcomponent to take the whole screen and the rendering system will do the rest?
z

Zach Klippenstein (he/him) [MOD]

07/23/2020, 11:15 PM
That wouldn’t help with stuff like animations, or anything else that’s not strictly drawing operations, that are tied to the composition of the background screen though, right?
r

romainguy

07/23/2020, 11:25 PM
If you recompose stuff that’s not visible you’ll pay the cost of recomposition
+ measure/layout
It’s only drawing that gets optimized away
s

shikasd

07/23/2020, 11:26 PM
I have an idea for that using subcomposition i want to play with at some point, where e.g. the image composable actually becomes the new screen so you don’t need any “shared element” stuff
Had a similar idea in mind, but it may be easier to get this done in compose terms 🙂
I think I was mostly referring to the cost of recomposing animation (like if it is dynamic vector) or relayouting if you, for example, have an autoscrolling column in the back.
t

Timo Drick

07/23/2020, 11:27 PM
I think the other approach would be to use layoutId modifier and use that. I am not sure but i think some of the compose team is working on doing transitions with that?
z

Zach Klippenstein (he/him) [MOD]

07/23/2020, 11:51 PM
l

Leland Richardson [G]

07/24/2020, 1:42 AM
we literally just had a meeting about this 🙂 The referenced CL is super interesting but will not help you out here. We are still debating ways to support enter/exit transitions at a more fundamental level. There’s a lot of factors to consider so we haven’t landed on one solution for this yet unfortunately 😕
👍 4
m

molikto

07/24/2020, 2:54 AM
I've been using a activity based backstack and it works quite well. I feel activity backed backstack works better because an activity is backed by a Window. Also I don't think destory an item in backstack when onPause is always desired. Another thing I'd like to know is before each View is an RenderNode, but now seems an entire scene is an RenderNode, how does it affect performance? (it seems it doesn't)
z

Zach Klippenstein (he/him) [MOD]

07/24/2020, 3:32 AM
now seems an entire scene is an RenderNode
I don’t think that’s true. I believe every “layer” in Compose is backed by a
RenderNode
, and a layer is created any time you use something like the
drawLayer
modifier, or the upcoming
withLayer
API.
In general, the nice thing about keeping the backstack in “app space” is that you have full control over it. E.g., if you want to work with a router API, you can use compose-router library. If you don’t need all that functionality, and just need a list with some animations, you can use something like compose-backstack. If you want a fancy, nested backstack solution, you can use something else or build something from scratch. Backstacks aren’t really a hard or interesting problem at the core, they’re just a stack. The tricky bits are transition animations and view state restoration, but those concerns needn’t be coupled to the mechanism your app uses to define history and navigation.
m

molikto

07/24/2020, 3:52 AM
for transition animation, I feel activity based animation is smoother, and I assumed it is because an Activity has it's own Window so it has it's own surface, so activity transition animation is performed by the window mananger but not your own app.
r

romainguy

07/24/2020, 3:56 AM
Note that the performance aspects of RenderNode is mostly around drawing commands recording and culling
More RenderNodes means more granular control over those two things
Anyway not something for you to worry about
z

Zach Klippenstein (he/him) [MOD]

07/24/2020, 4:12 AM
I don’t think there’s anything inherent about window transitions that is cheaper than regular layer transitions. Layout animations are more expensive than pure layer transformations. Software layers are usually slower than hardware layers. I would be curious to see an example of where you’ve noticed window animations are smoother than in-app ones, I haven’t noticed that in any recent android versions except for the occasional bad app.
r

romainguy

07/24/2020, 4:17 AM
Window animations are definitely cheaper
They are handled directly by the hardware composer, we don't even go through the GPU
But on recent devices it won't make a huge difference
z

Zach Klippenstein (he/him) [MOD]

07/24/2020, 4:18 AM
TIL
r

romainguy

07/24/2020, 6:33 AM
It’s also why SurfaceViews are better than TextureView
They go directly to the hardware composer when possible, so you can skip an extra GPU composition step
z

Zach Klippenstein (he/him) [MOD]

07/24/2020, 1:05 PM
So RenderNodes are still composited using the GPU?
r

romainguy

07/24/2020, 3:00 PM
Render nodes contain drawing commands for the GPU yes