Improved viewmodel logic for #39.
- added separate factories for VMs that require the synchronizer and those that do not - witched to using the factories directly, instead of creating providers, similar to how Google does it in their generic extension functions but removed the need to inject the factory
This commit is contained in:
parent
ac626917f4
commit
1937c19a14
|
@ -4,39 +4,18 @@ import androidx.fragment.app.FragmentActivity
|
|||
import androidx.lifecycle.ViewModelProvider
|
||||
import cash.z.ecc.android.di.annotation.ActivityScope
|
||||
import cash.z.ecc.android.di.module.MainActivityModule
|
||||
import cash.z.ecc.android.di.module.ViewModelsModule
|
||||
import cash.z.ecc.android.ui.MainActivity
|
||||
import cash.z.ecc.android.ui.detail.WalletDetailFragment
|
||||
import cash.z.ecc.android.ui.home.HomeFragment
|
||||
import cash.z.ecc.android.ui.receive.ReceiveFragment
|
||||
import cash.z.ecc.android.ui.send.SendAddressFragment
|
||||
import cash.z.ecc.android.ui.send.SendConfirmFragment
|
||||
import cash.z.ecc.android.ui.send.SendFinalFragment
|
||||
import cash.z.ecc.android.ui.send.SendMemoFragment
|
||||
import cash.z.ecc.android.ui.setup.BackupFragment
|
||||
import cash.z.ecc.android.ui.setup.LandingFragment
|
||||
import dagger.BindsInstance
|
||||
import dagger.Subcomponent
|
||||
import javax.inject.Named
|
||||
|
||||
@ActivityScope
|
||||
@Subcomponent(modules = [MainActivityModule::class, ViewModelsModule::class])
|
||||
@Subcomponent(modules = [MainActivityModule::class])
|
||||
interface MainActivitySubcomponent {
|
||||
|
||||
fun inject(activity: MainActivity)
|
||||
|
||||
// Fragments
|
||||
fun inject(fragment: HomeFragment)
|
||||
fun inject(fragment: ReceiveFragment)
|
||||
fun inject(fragment: SendAddressFragment)
|
||||
fun inject(fragment: SendMemoFragment)
|
||||
fun inject(fragment: SendConfirmFragment)
|
||||
fun inject(fragment: SendFinalFragment)
|
||||
fun inject(fragment: WalletDetailFragment)
|
||||
fun inject(fragment: LandingFragment)
|
||||
fun inject(fragment: BackupFragment)
|
||||
|
||||
fun viewModels(): ViewModelProvider
|
||||
fun viewModelFactory(): ViewModelProvider.Factory
|
||||
@Named("BeforeSynchronizer") fun viewModelFactory(): ViewModelProvider.Factory
|
||||
|
||||
@Subcomponent.Factory
|
||||
interface Factory {
|
||||
|
|
|
@ -2,35 +2,30 @@ 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
|
||||
|
||||
|
||||
inline fun <reified VM : ViewModel> MainActivity.viewModel() = object : Lazy<VM> {
|
||||
val cached: VM? = null
|
||||
override fun isInitialized(): Boolean = cached != null
|
||||
override val value: VM get() {
|
||||
return cached ?: component.viewModels()[VM::class.java]
|
||||
}
|
||||
}
|
||||
|
||||
inline fun <reified VM : ViewModel> BaseFragment<*>.viewModel() = object : Lazy<VM> {
|
||||
val cached: VM? = null
|
||||
override fun isInitialized(): Boolean = cached != null
|
||||
override val value: VM get() {
|
||||
return if (cached != null) cached else {
|
||||
val factory = mainActivity?.component?.viewModelFactory()
|
||||
?: throw IllegalStateException("Error: mainActivity should not be null by the time the ${VM::class.java.simpleName} viewmodel is lazily accessed!")
|
||||
ViewModelProvider(this@viewModel, factory)[VM::class.java]
|
||||
}
|
||||
}
|
||||
override val value: VM
|
||||
get() = cached
|
||||
?: ViewModelProvider(this@viewModel, scopedFactory<VM>())[VM::class.java]
|
||||
}
|
||||
|
||||
inline fun <reified VM : ViewModel> BaseFragment<*>.activityViewModel() = object : Lazy<VM> {
|
||||
inline fun <reified VM : ViewModel> BaseFragment<*>.activityViewModel(isSynchronizerScope: Boolean = true) = object : Lazy<VM> {
|
||||
val cached: VM? = null
|
||||
override fun isInitialized(): Boolean = cached != null
|
||||
override val value: VM get() {
|
||||
return cached ?: mainActivity?.component?.viewModels()?.get(VM::class.java)
|
||||
?: throw IllegalStateException("Error: mainActivity should not be null by the time the ${VM::class.java.simpleName} activityViewModel is lazily accessed!")
|
||||
}
|
||||
override val value: VM
|
||||
get() {
|
||||
return cached
|
||||
?: scopedFactory<VM>(isSynchronizerScope)?.let { factory ->
|
||||
ViewModelProvider(this@activityViewModel.mainActivity!!, factory)[VM::class.java]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline fun <reified VM : ViewModel> 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!")
|
||||
}
|
|
@ -2,11 +2,9 @@ package cash.z.ecc.android.di.viewmodel
|
|||
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import cash.z.ecc.android.di.annotation.ActivityScope
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Provider
|
||||
|
||||
@ActivityScope
|
||||
class ViewModelFactory @Inject constructor(
|
||||
private val creators: Map<Class<out ViewModel>, @JvmSuppressWildcards Provider<ViewModel>>
|
||||
) : ViewModelProvider.Factory {
|
||||
|
@ -14,8 +12,8 @@ class ViewModelFactory @Inject constructor(
|
|||
val creator = creators[modelClass] ?: creators.entries.firstOrNull {
|
||||
modelClass.isAssignableFrom(it.key)
|
||||
}?.value ?: throw IllegalArgumentException(
|
||||
"No map entry found for ${modelClass.canonicalName}." +
|
||||
" Verify that this ViewModel has been added to the ViewModelModule."
|
||||
"No map entry found for ${modelClass.canonicalName}. Verify that this ViewModel has" +
|
||||
" been added to the ViewModelModule. ${creators.keys}"
|
||||
)
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return creator.get() as T
|
||||
|
|
Loading…
Reference in New Issue