Injected ViewModel Provider
This is a small lib to use easily use Android's ViewModels with a depedency injection framework like dagger. You obtain a ViewModel
from a javax.inject.Provider
instead of a ViewModelProvider.Factory
.
Usage
From Java
Download
implementation("me.tatarka.injectedvmprovider:injectedvmprovider:3.0.0")
Usage
Set up your ViewModel
public class MyViewModel extends ViewModel {
private final MyDependency source;
@Inject
public MainViewModel(MyDependency source) {
this.source = source;
}
}
Inject your ViewModel provider into the desired Fragment or Activity
public class MyActivity extends AppCompatActivity {
@Inject
Provider<MyViewModel> vmProvider;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
MyViewModel vm = InjectedViewModelProvider.of(this).get(vmProvider);
}
}
If you have a factory, you can inject that instead. This is useful for passing in intent arguments to the view model, and/or with assisted injection. For the key, you can either pass the factory instance or the view model class.
class MyActivity extends ComponentActivity {
@Inject
MyViewModel.Factory vmFactory;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MyViewModel vm = InjectedViewModelProvider.of(this).get(vmFactory, factory -> factory.create("arg"));
MyViewModel vm2 = InjectedViewModelProvider.of(this).get(MyViweModel.class, () -> vmFactory.create("arg"));
}
}
From Kotlin
Download
implementation 'me.tatarka.injectedvmprovider:injectedvmprovider-ktx:3.0.0'
// or if you are using fragments
implementation 'me.tatarka.injectedvmprovider:injectedvmprovider-fragment-ktx:3.0.0'
Usage
Set up your ViewModel
class MyViewModel @Inject constructor(val source: MyDependency): ViewModel()
Use the viewModels
delegate to obtain a view model from an injected provider.
class MyFragment @Inject constructor(val vmProvider: Provider<MyViweModel>) {
val vm by viewModels(vmProvider)
}
If you have field injection or are using a factory, you pass a lambda to view model instead. This lambda will provide a SavedStateHandle
that you may pass along to your view model.
class MyActivity: ComponentActivity {
@Inject
latinit var vmProvider: Provider<MyViewModel>
@Inject
latinit var vmFactory: MyViewModel.Factory
val vm by viewModel { vmProvider.get() }
val vm2 by viewModel { handle -> vmFactory.create(handle) }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
inject(this)
}
}