问题
My ViewModelFactory:
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")
}
}
Activity:
@Inject
lateinit var viewModelFactory: ViewModelFactory
protected val viewModel: ViewModel by lazy { ViewModelProvider(this, viewModelFactory).get(getViewModelClass()) }
ViewModel:
@AssistedInject.Factory
interface Factory : ViewModelAssistedFactory<SplashViewModel>
And I was wondering how can I provide the defaultArgs dynamically instead of:
ActivityModule
@Module
companion object {
@JvmStatic
@Nullable
@Provides
fun provideDefaultArgs(): Bundle? {
return null
}
}
The idea is to have the possibility to send a parameter to the ViewModel, let's say an ID for a DetailActivity.
Normally I use an "init" method, but If I could use the StateHandle map
would be even better. Something like this and this.
Makes sense? Is it possible?
回答1:
I think the best alternative is:
Create a Factory
without injected dependencies:
class ViewModelFactoryAlt<out V : ViewModel>(
private val viewModelFactory: ViewModelAssistedFactory<V>,
owner: SavedStateRegistryOwner,
defaultArgs: Bundle? = null
) : AbstractSavedStateViewModelFactory(owner, defaultArgs) {
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel> create(key: String, modelClass: Class<T>, handle: SavedStateHandle): T {
return viewModelFactory.create(handle) as T
}
}
Create our ViewModelAssitedFactory
like:
class HelloWorldViewModelFactory @Inject constructor(
private val dependencyA: DependencyA,
...
) : ViewModelAssistedFactory<HelloWorldViewModel> {
override fun create(stateHandle: SavedStateHandle): HelloWorldViewModel {
return HelloWorldViewModel(stateHandle, dependencyA, ...)
}
}
And finally:
@Inject
lateinit var factory: HelloWorldViewModelFactory
private val viewModel: HelloWorldViewModel by viewModels { ViewModelFactoryAlt(factory, this, intent.extras) }
This post by Elye saved my life.
来源:https://stackoverflow.com/questions/59896120/how-to-dynamically-set-the-bundle-from-abstractsavedstateviewmodelfactory