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

Tgo1014

04/29/2022, 2:13 PM
Is there already a way to scope view models by composable?
a

Adam Powell

04/29/2022, 2:16 PM
short answer: yes. longer answer: what specific scoping behavior do you want, what code do you want to be able to write?
t

Tgo1014

04/29/2022, 2:16 PM
Let’s say I’ve a pager with the same composable and each needs their own instance of the same viewmodel. How would I do that?
a

Adam Powell

04/29/2022, 2:32 PM
have each of your pages provide
LocalViewModelStoreOwner
and multiplex them into a host viewmodel; this is how androidx navigation-compose does it
you'll have some decisions to make around the intended lifecycle of those viewmodels, how long to keep them alive and when to clear them if you don't keep all of the pager's pages composed at the same time
t

Tgo1014

04/29/2022, 2:34 PM
so it requires some work I see, I’ll have to create some custom implementation of
LocalViewModelStoreOwner
right? I need to check how the navigation does it then
a

Adam Powell

04/29/2022, 2:37 PM
a little work, but not too much. the usual way to think about this is to have the composable function that provides the
LocalViewModelStoreOwner
fetch a container ViewModel that you write for this purpose. Then use a
RememberObserver
to remove+clear the
ViewModelStore
when a page leaves the composition if the host activity
isChangingConfiguration
isn't
true
(since if you're tearing down the composition for a config change you want to leave them alone)
the reason to use
RememberObserver
directly instead of
DisposableEffect
is because you need to hook
onAbandoned
too; ViewModels are created during composition and need to be cleaned up if the composition they were created in doesn't commit
shouldn't be more than ~70-100 lines of utility code that you write once and don't have to look at again 🙂
t

Tgo1014

04/29/2022, 2:42 PM
Very detailed reply, thanks for the help Adam! 😄
👍 1
a

Adam Powell

04/29/2022, 2:45 PM
you're welcome; I was just doing this recently for a personal project a couple weeks ago so it was fresh 😄
t

Tgo1014

04/29/2022, 2:52 PM
Do you think in the future it could be included directly on
hilt
? Like specifying some key would get another view model and all calls for the same key would return the same? Is this even possible? haha
a

Adam Powell

04/29/2022, 4:01 PM
I'm not quite sure I understand the question or the relation to hilt; this is lower-level than hilt and you don't need hilt to do it
j

julioromano

04/29/2022, 6:00 PM
have each of your pages provide
LocalViewModelStoreOwner
and multiplex them *into a host viewmodel*; this is how androidx navigation-compose does it
@Adam Powell (I think I have an English problem here) can you explain with different words what do you mean by “multiplex them into a host viewmodel” ? Thanks!
a

Adam Powell

04/29/2022, 6:39 PM
my apologies; you have a point where you need to create one
ViewModelStore
per page, each one establishes a namespace and scope for viewmodels obtained beneath it. You need a place to store those `ViewModelStore`s and make sure they're retained. Using another
ViewModel
is the most straightforward way to do this since it already provides all of the facilities and guarantees you want. You'll create your own
ViewModel
that stores a map of some key that is unique for each page to a
ViewModelStore
, and you'll need to manage the addition and removal of these `ViewModelStore`s from that map. Then you'll need to provide the correct
ViewModelStore
via
LocalViewModelStoreOwner
to the content of each page.
🙌 1
🙏 2
28 Views