Как динамически установить пакет из AbstractSavedStateViewModelFactory - PullRequest
2 голосов
/ 24 января 2020

Моя 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")
    }
}

Активность :

@Inject
lateinit var viewModelFactory: ViewModelFactory
protected val viewModel: ViewModel by lazy { ViewModelProvider(this, viewModelFactory).get(getViewModelClass()) }

ViewModel :

@AssistedInject.Factory
interface Factory : ViewModelAssistedFactory<SplashViewModel>

И мне было интересно, как я могу динамически предоставлять defaultArgs вместо:

ActivityModule

@Module
    companion object {
        @JvmStatic
        @Nullable
        @Provides
        fun provideDefaultArgs(): Bundle? {
            return null
        }
    }

Идея состоит в том, чтобы иметь возможность отправлять параметр для ViewModel, скажем, идентификатор для DetailActivity. Обычно я использую метод "init", но если бы я мог использовать StateHandle map, было бы еще лучше. Что-то вроде это и это .

Имеет смысл? Возможно ли это?

1 Ответ

0 голосов
/ 22 апреля 2020

Я думаю, что лучшая альтернатива:

Создайте Factory без введенных зависимостей:

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
    }
}

Создайте наш ViewModelAssitedFactory как:

class HelloWorldViewModelFactory @Inject constructor(
    private val dependencyA: DependencyA,
    ...
) : ViewModelAssistedFactory<HelloWorldViewModel> {
    override fun create(stateHandle: SavedStateHandle): HelloWorldViewModel {
        return HelloWorldViewModel(stateHandle, dependencyA, ...)
    }
}

И наконец:

@Inject
lateinit var factory: HelloWorldViewModelFactory
private val viewModel: HelloWorldViewModel by viewModels { ViewModelFactoryAlt(factory, this, intent.extras) }

Этот пост от Elye спас мне жизнь.

...