From 35d268622cd00bf4b1a0d0663803b4d679d9edc6 Mon Sep 17 00:00:00 2001 From: Kevin Gorham Date: Thu, 27 Aug 2020 20:19:07 -0400 Subject: [PATCH] Allow ViewModel injection from the MainActivity. --- .../ecc/android/di/viewmodel/ViewModelExt.kt | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/app/src/main/java/cash/z/ecc/android/di/viewmodel/ViewModelExt.kt b/app/src/main/java/cash/z/ecc/android/di/viewmodel/ViewModelExt.kt index 253e601..17f5e14 100644 --- a/app/src/main/java/cash/z/ecc/android/di/viewmodel/ViewModelExt.kt +++ b/app/src/main/java/cash/z/ecc/android/di/viewmodel/ViewModelExt.kt @@ -2,6 +2,7 @@ package cash.z.ecc.android.di.viewmodel import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider +import cash.z.ecc.android.ui.MainActivity import cash.z.ecc.android.ui.base.BaseFragment @@ -35,4 +36,26 @@ inline fun BaseFragment<*>.activityViewModel(isSynchron inline fun BaseFragment<*>.scopedFactory(isSynchronizerScope: Boolean = true): ViewModelProvider.Factory { val factory = if (isSynchronizerScope) mainActivity?.synchronizerComponent?.viewModelFactory() else mainActivity?.component?.viewModelFactory() return factory ?: throw IllegalStateException("Error: mainActivity should not be null by the time the ${VM::class.java.simpleName} viewmodel is lazily accessed!") +} + +/** + * Create a viewModel that is scoped to the lifecycle of the activity. This viewModel will be + * created from the `synchronizerComponent` rather than the `component`, meaning the synchronizer + * will be available but this also requires that this view model not be accessed before the + * synchronizerComponent is ready. Doing so will throw an exception. + */ +inline fun MainActivity.activityViewModel() = object : Lazy { + val cached: VM? = null + override fun isInitialized(): Boolean = cached != null + override val value: VM + get() { + return cached + ?: this@activityViewModel.run { + if (isInitialized) { + ViewModelProvider(this, synchronizerComponent.viewModelFactory())[VM::class.java] + } else { + throw IllegalStateException("Error: the SynchronizerComponent must be initialized before the ${VM::class.java.simpleName} viewmodel is lazily accessed!") + } + } + } } \ No newline at end of file