Will compose attempt to handle navigation, backsta...
# compose
u
Will compose attempt to handle navigation, backstack etc -- or will a "screen" framework be needed?
v
It should be coming soon. It will integrate nicely with Navigation components.
Not release yet so wait for a couple weeks.
❤️ 2
There are community projects until then if you are interested - https://github.com/zsoltk/compose-router && https://github.com/zach-klippenstein/compose-backstack
j
@Vinay Gaba the next release will have compose support?
i
Not this next release, but soon after, yep
❤️ 2
🙏🏼 3
h
Sorry, this turned out to be wordy. Having looked at the CL of new NavHost for compose, it seems like each destination is bundled with a composable function, which gets replaced everytime the stack is updated. This also suggests that upon back navigation, the previous composable gets recalled since it was removed from the UI when a new view had entered the stack. But,
LazyColumnFor
,
LazyRowFor
and many other scrolling components don't share their scroll state. I haven't found a way to completely restore a state for a composable which has scrolling child components. That's why, if I scroll down a list of items and visit the detail screen for one of them and come back, scroll state will be completely lost. Would it be possible to use actual
Stack
composable to render all backstack from a NavHost?
l
scrollstate uses the saved instance state mechanism and will be restored properly with NavHost
that said, i’m pretty sure the final APIs for Lazy* components should allow for the lifting of their scrollstate
u
sooo, where would my viewmodel instance live for it to survive screen changes (and config changes)? as a field on some back stack entry object?
l
also, i would like us to explore a navigation approach where the compositions on the backstack are actually kept, and potentially in some de-prioritized state, so that we don’t have to recompose the entire screen on back navigation
👍 3
u
hmm I'd say mostly not necessary, fragments destroy their view on
replace
but then you need it for dialogs and crap
l
the current (work in progress) CL has a different lifecycleowner provided for each backstack entry IIRC. this means if you do something like
val myVm = viewModel<MyViewModel>()
then it will have the lifetime that you want
yeah i’m not saying its necessary, but we have a new compose runtime API that we’re thinking about that could be utilized here and it might make some transition animations smoother
these are great questions, btw! these are def. the kinds of things we are thinking about
u
yea sometimes its gets heavy for fragment/conductor when you have nested fragments in them, since those get created only in fragment.onCreateView, sicne it needs a container view to put the child into, so yes backing to this would need to recreate a loot of stuff, like for example the very common screen with bottom navigation, where each tab is a child; but usually I just dont care and seems to be okay
btw since I mentioned dialogs, are those meant to be as part of the composable view hierarchy just on Z axis, or will it be a window thing as it is now
l
our dialog composable uses the platform window manager and creates a new window and then composes into that
u
so one is expected to keep state.showFooDialog : Boolean, and then set it to false onDialogDismissClicked?
l
yeah
u
I see, so I presume the actual showing of the dialog will be idempotent unlike in current framework, great
i
NavHost takes care of providing a per screen Lifecycle, ViewModelStore, SavedState, etc. Just use them like normally in your Composable and we'll already be swapping them out and updating them as you navigate between screens. Should be totally transparent to your Composable whether they are in a NavHost or not
Which, FWIW, makes testing an individual screen way easier to do in isolation - something we're thinking a lot about as well
💯 5
g
Will this lifecycle be active only while nav item is visible? Or there is some sort of lifecycle of backstack (because there is a way to return back to previous screen)
r
So since we need to use
val vm = viewModel<XViewModel>()
inside the composable, we should be passing view model factories to the composable as argument and not the viewmodel itself
i
NavBackStackEntry's Lifecycle is already part of the public API surface: https://developer.android.com/guide/navigation/navigation-programmatic#navbackstackentry - paused when a floating window (read: dialog) destination is above it, stopped when it is no longer visible, destroyed when popped off the back stack
👍 1
Part of the Kotlin DSL for building your navigation graph will be giving you a lambda where you can parse out arguments, construct a scoped ViewModel, etc. that you can then pass to your Composable (or just inline everything for prototyping - you get to choose how segmented everything is), so really up to you on what you put there vs directly in your Composable
u
Do you believe dagger subcomponents should live on try entry as well?