Gui*_*lhE 7 android android-lifecycle dagger-2 android-viewmodel viewmodel-savedstate
我的视图模型工厂:
class ViewModelFactory @Inject constructor(
private val viewModelMap: MutableMap<Class<out ViewModel>, ViewModelAssistedFactory<out ViewModel>>,
owner: SavedStateRegistryOwner,
defaultArgs: Bundle?
) : AbstractSavedStateViewModelFactory(owner, defaultArgs) {
@Throws(IllegalStateException::class)
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel?> create(key: String, modelClass: Class<T>, handle: SavedStateHandle): T {
return viewModelMap[modelClass]?.create(handle) as? T ?: throw IllegalStateException("Unknown ViewModel class")
}
}
Run Code Online (Sandbox Code Playgroud)
活动:
@Inject
lateinit var viewModelFactory: ViewModelFactory
protected val viewModel: ViewModel by lazy { ViewModelProvider(this, viewModelFactory).get(getViewModelClass()) }
Run Code Online (Sandbox Code Playgroud)
视图模型:
@AssistedInject.Factory
interface Factory : ViewModelAssistedFactory<SplashViewModel>
Run Code Online (Sandbox Code Playgroud)
我想知道如何动态提供 defaultArgs 而不是:
活动模块
@Module
companion object {
@JvmStatic
@Nullable
@Provides
fun provideDefaultArgs(): Bundle? {
return null
}
}
Run Code Online (Sandbox Code Playgroud)
这个想法是能够向 ViewModel 发送一个参数,比如说 DetailActivity 的 ID。通常我使用“init”方法,但如果我可以使用StateHandle map会更好。像这样和这样的东西。
说得通?是否可以?
我遇到了两种解决方案:
\n\n方案一:
\n\n将我们的 ViewModelFactory 更改为:
\n\nclass ViewModelFactory @Inject constructor(\n private val viewModelMap: MutableMap<Class<out ViewModel>, ViewModelAssistedFactory<out ViewModel>>\n) {\n fun create(owner: SavedStateRegistryOwner, defaultArgs: Bundle? = null): AbstractSavedStateViewModelFactory {\n return object : AbstractSavedStateViewModelFactory(owner, defaultArgs) {\n @Suppress("UNCHECKED_CAST")\n override fun <T : ViewModel?> create(key: String, modelClass: Class<T>, handle: SavedStateHandle): T {\n return viewModelMap[modelClass]?.create(handle) as? T ?: throw IllegalStateException("Unknown ViewModel class")\n }\n }\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n\n最后:
\n\n@Inject\nlateinit var viewModelFactory: ViewModelFactory\nprotected val viewModel: ViewModel by lazy { ViewModelProvider(this, viewModelFactory.create(this, args).get(getViewModelClass()) }\nRun Code Online (Sandbox Code Playgroud)\n\n另外,我们可以将 ActivityModule 简化为(示例):
\n\n@AssistedModule\n@Module(includes = [AssistedInject_SplashActivityModule::class])\nabstract class SplashActivityModule{\n\n @Binds\n @IntoMap\n @ViewModelKey(SplashViewModel::class)\n abstract fun bindFactory(factory: SplashViewModel.Factory): ViewModelAssistedFactory<out ViewModel>\n}\nRun Code Online (Sandbox Code Playgroud)\n\nTom\xc3\xa1\xc5\xa1 Mlynari\xc4\x8d的这篇文章帮助解决了这个问题。
\n\n方案B:
\n\n创建一个Factory没有注入依赖项的:
class ViewModelFactoryAlt<out V : ViewModel>(\n private val viewModelFactory: ViewModelAssistedFactory<V>,\n owner: SavedStateRegistryOwner,\n defaultArgs: Bundle? = null\n) : AbstractSavedStateViewModelFactory(owner, defaultArgs) {\n\n @Suppress("UNCHECKED_CAST")\n override fun <T : ViewModel> create(key: String, modelClass: Class<T>, handle: SavedStateHandle): T {\n return viewModelFactory.create(handle) as T\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n\n创建我们的ViewModelAssitedFactory喜欢:
class HelloWorldViewModelFactory @Inject constructor(\n private val dependencyA: DependencyA,\n ...\n) : ViewModelAssistedFactory<HelloWorldViewModel> {\n override fun create(stateHandle: SavedStateHandle): HelloWorldViewModel {\n return HelloWorldViewModel(stateHandle, dependencyA, ...)\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n\n最后:
\n\n@Inject\nlateinit var factory: HelloWorldViewModelFactory\nprivate val viewModel: HelloWorldViewModel by viewModels { ViewModelFactoryAlt(factory, this, intent.extras) }\nRun Code Online (Sandbox Code Playgroud)\n\n这篇文章由埃莱帮助解决了这个问题。
\n| 归档时间: |
|
| 查看次数: |
2196 次 |
| 最近记录: |