I have single Activity application.
I want to bind viewModel to the parent fragment lifecycle (FlowFragmentLogin
), and share it with child fragments (CellFragment
, InfoFragment
, etc
). So that when I move from FlowFragmentLogin
to FlowFragmentMain
, viewModel onCleared()
was called.
But the only way I found is to share viewModel between Activity, and it's Fragments: https://insert-koin.io/docs/1.0/documentation/koin-android/index.html
And no control over lifecycle-owners. Wich is unacceptable for me, at least because this viewModel will live until the application's death.
Since Navigation 2.1.0-alpha02
:
You can now create ViewModels that are scoped at a navigation graph level via the by navGraphViewModels() property delegate for Kotlin users or by using the getViewModelStore() API added to NavController.
You can find the change log here and the document.
Unfortunately Koin can not support the feature since viewModel()
or sharedViewModel()
was bond to Activity. But support for nav has already planned in 2.1.x
and you can track here.
For now here's my solution:
navGraphViewModels()
instead of viewModel()
in Koin.class DetailFr : Fragment() {
private val vm: DetailViewModel by navGraphViewModels(R.id.main_nav_graph)
}
KoinComponent
so that we can use by inject()
instead of inject by constructor.class DetailViewModel : ViewModel(), KoinComponent {
private val repo: DetailRepository by inject()
// othetr objects you need
}
Hopefully this helps
You can do it by using new version of Koin(2.1.0) and some magic :)
All you need is add this extension function:
inline fun <reified VM : ViewModel> Fragment.sharedGraphViewModel(
@IdRes navGraphId: Int,
qualifier: Qualifier? = null,
noinline parameters: ParametersDefinition? = null
) = lazy {
val store = findNavController().getViewModelStoreOwner(navGraphId).viewModelStore
getKoin().getViewModel(ViewModelParameter(VM::class, qualifier, parameters, null, store, null))
}
And now you can simple get your ViewModel from nested graph by:
private val viewModel: MyViewModel by sharedGraphViewModel(R.id.my_graph)
In Koin version 3.1.3
there is a new extension function koinNavGraphViewModel
.
just add the following dependency
implementation "io.insert-koin:koin-androidx-navigation:$koin_version"
It can be used like this
private val viewModel: MyViewModel by koinNavGraphViewModel(R.id.my_graph)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With