Использование конструктора ViewModel вместо ViewModelProvider для возможности получения данных из базы данных Room на основе параметров - PullRequest
2 голосов
/ 11 января 2020

При использовании базы данных Room с ViewModel и LiveDate на основе этого codelab , чтобы использовать запросы с параметром, я не нашел никакого решения, поэтому Я пытался создать другой конструктор для обоих классов модели представления и класс репозитория , но я заметил, что в CodeLab они вообще не используют конструкторы модели представления , а вместо этого они используют провайдера модели представления, поэтому я изменил его и использовал
new StoryViewModel(getApplication(),"Fiction");
вместо
new ViewModelProvider(this).get(StoryViewModel.class);

Я не знаю, есть ли что-то не так с этим или нет.
Теперь все отлично работает , но если это так почему бы нам не использовать это всегда?
И почему мы используем провайдера модели представления?

Если то, что я сделал, неверно, то как мне получить данные из БД на основе параметров?

Спасибо.

Ответы [ 2 ]

1 голос
/ 12 января 2020

Вы не должны использовать непосредственно конструктор viewModel, потому что система создает viewModel или получает его из кэша. Если вы хотите передать параметр конструктору viewModel, вы должны использовать фабрику viewModel, например:

class ViewModelFactory(params) : ViewModelProviders.Factory {

     override fun <T : ViewModel> create(modelClass: Class<T>): T {
          return modelClass.getConstructor(params::class.java).newInstance(params);
     }

}

...

override fun onCreate(...) {

  viewModel = ViewModelProviders.of(this, ViewModelFactory(params)).get(MyViewModel::class.java)s
}
0 голосов
/ 04 апреля 2020

Вот полный пример, построенный на знаниях, которые я получил из ответа Пьерлуиджи:

class MyFragment: Fragment() {
    private lateinit var viewModel: ContactViewModel

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)

        activity?.let { activity ->
            viewModel = ViewModelProvider(
                activity,
                MyViewModelFactory(
                    "mode value",
                    "nickname value"
                )
            ).get(MyViewModel::class.java)
        } ?: throw AssertionError("Unable to get parent activity from fragment")
    }
}

class MyViewModelFactory(val mode: String, val nickname: String) : ViewModelProvider.Factory {
    override fun <T : ViewModel?> create(modelClass: Class<T>): T =
        modelClass.getConstructor(String::class.java, String::class.java)
            .newInstance(mode, nickname)
}

class MyViewModel(val mode: String, val nickname: String) : ViewModel()
...