Hi there, I'm using Hilt to inject dependencies. I...
# compose
m
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
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
@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
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
😀 thank you
t
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
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
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
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
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
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
m
Wow amazing, I didn't see it coming 🙂
c
https://medium.com/androiddevelopers/animations-in-navigation-compose-36d48870776b Just released yesterday. So you're finding out about it right on time. 😄
❤️ 1
k
@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
@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
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
@knthmn with hilt you need to use
hiltViewModel<T>()
which, afaik, doesn’t have a “key” parameters to define a scope
k
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
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
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