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

MaxUt

08/05/2021, 7:43 AM
Hi there, I'm using Hilt to inject dependencies. I was wondering if it's possible to instanciate an object which contains depencies (injected with Hilt) in a Composable ?
I was expecting to able to do something like this :
Copy code
class SearchViewManager @Inject constructor(
    val catalogManager: CatalogManager,
    private val _widgetManager: WidgetsManager
) { 
    ... 
}

@Composable
fun SearchScreen() {
    val searchViewManager: SearchViewManager = SearchViewManager()
}
However, it seems like I have to pass the parameters.
c

Colton Idle

08/05/2021, 1:40 PM
I pass a ScreenViewModel into my Screen, but it's all setup via hilt and
hiltViewModel()
See: https://developer.android.com/jetpack/compose/libraries#hilt
m

MaxUt

08/05/2021, 2:14 PM
@Colton Idle thanks for the tip. Is there a way to have one view model per instance of a composable ? The idea is that I don't want to share the same viewModel instance across SearchScreen composable. For now I instanciated 3 SearchViewManager in the MainActivity that I pass down to the different SearchScreen composable via parameters but I find this solution a bit complicated. Any idea ?
c

Colton Idle

08/05/2021, 2:18 PM
I still don't feel comfortable with answering this (don't want to misinform). May want to wait for someone else to chime in on the scoping question. Maybe/hopefully Ian Lake can chime in. He's always helpful 😄
m

MaxUt

08/05/2021, 2:19 PM
😀 thank you
t

Tgo1014

08/05/2021, 2:22 PM
There isn’t yet scope for injection. Here is the feature request, theres a workaround on it: https://issuetracker.google.com/issues/165642391
🙂 1
c

Colton Idle

08/05/2021, 2:24 PM
As far as I know (I could be wrong), the ViewModel scope will always outlive the screen and be shared if you have multiple of those screens visible. So lets say you had ScreenAViewModel and then
Copy code
Column{
ScreenA
ScreenA
}
then whatever change you make in the top screenA, should also be shown in the bottom screenA.
m

MaxUt

08/05/2021, 2:25 PM
Yes exactly, from what I understood the viewModel is tied to the lifecycle of the Activity. In my case I'd like to have multiple instance of a viewModel.
c

Colton Idle

08/05/2021, 2:26 PM
Looks like maybe this is handled with compose nav? As per that issue "Ian, I believe this is covered with navigation. Can you confirm and close?"
t

Tgo1014

08/05/2021, 2:29 PM
I guess if you navigate from one screen to another you can do it with the nav scope. My case with pagers doesn’t work very well as the screens are “alive” at same time
m

MaxUt

08/05/2021, 2:33 PM
Right, the navigation might do the trick. I'm a bit in the same situation as you @Tgo1014, I'm not using the standard navigation library (I need slideIn/Out transition which haven't been released yet)
👍 1
t

Tgo1014

08/05/2021, 2:35 PM
m

MaxUt

08/05/2021, 2:35 PM
Wow amazing, I didn't see it coming 🙂
c

Colton Idle

08/05/2021, 2:36 PM
https://medium.com/androiddevelopers/animations-in-navigation-compose-36d48870776b Just released yesterday. So you're finding out about it right on time. 😄
❤️ 1
k

knthmn

08/06/2021, 7:29 AM
@MaxUt idk if this is what you want, but you can pass
key
in
hiltViewModel()
(or
viewModel()
) to get several viewmodels in the same scope.
Copy code
val a = viewModel<FooVM>(key = "1")
val b = viewModel<FooVM>(key = "2")
println(a === b) // false
t

Tgo1014

08/06/2021, 7:58 AM
@knthmn the problem with this is that it doesn’t inject automatically, so you have inject in the activity and pass everything as parameters, which works, but doesn’t look very clean
k

knthmn

08/06/2021, 8:09 AM
use
@HiltViewModel
from
com.google.dagger:hilt-android
https://developer.android.com/training/dependency-injection/hilt-jetpack#viewmodels edit: I checked
hiltViewModel()
doesn't provide a
key
parameter, however you can copy the function and add the
key
parameter that is passed to
viewModel()
.
t

Tgo1014

08/06/2021, 8:12 AM
@knthmn with hilt you need to use
hiltViewModel<T>()
which, afaik, doesn’t have a “key” parameters to define a scope
k

knthmn

08/06/2021, 8:16 AM
check my edit above, the only thing
hiltViewModel()
does is hook in the factory for creating the vm, i think it is safe to add a key parameter to it.
t

Tgo1014

08/06/2021, 8:18 AM
I’m trying it now, will report back in a few minutes
Doesn’t work:
java.lang.IllegalArgumentException: SavedStateProvider with the given key is already registered
k

knthmn

08/06/2021, 8:27 AM
Sorry I didn't verify and got your hopes up. They changed how it is implemented. https://github.com/google/dagger/issues/2328 This worked when it used to be
@ViewModelInject
(which I used a few months ago)
👍 1
2 Views