Какой ViewModelStoreOwner использовать для ViewModelProvider во фрагменте? - PullRequest
2 голосов
/ 22 апреля 2020

Я создал тестовое действие, которое обновляет некоторый текст в моей MyViewModel.

Я хотел бы наблюдать эти изменения в Фрагмент , но когда я использую

MyViewModel myViewModel = new ViewModelProvider(this).get(MyViewModel.class);

это дает мне другой экземпляр MyViewModel, чем тот, который использовался в действии, что приводит к тому, что мой onChanged() обратный вызов во фрагменте не вызывается.

Только когда я изменяю тот же самый фрагмент кода на

HomeViewModel homeViewModel = new ViewModelProvider(getActivity()).get(HomeViewModel.class);

получает ли фрагмент тот же экземпляр MyViewModel, что и действие - поэтому успешно вызывается onChanged().

Однако я не уверен, если использовать getActivity() в качестве ViewModelStoreOwner - это правильный способ работы, поскольку я нигде не видел этого ни в каких примерах. Мне интересно, может ли быть лучший ViewModelStoreOwner, который я должен использовать в этом случае?

Ответы [ 3 ]

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

Мне интересно, может ли быть лучший ViewModelStoreOwner, который я должен использовать в этом случае?

Вы должны использовать activity экземпляр для совместного использования одного и того же экземпляра среди фрагментов в то же действие.

Обе операции и Фрагмент реализуют свой собственный интерфейс ViewModelStoreOwner и реализуют метод getViewModelStore(). getViewModelStore() предоставляет экземпляр ViewModelStore, который используется для хранения объектов viewmodel, созданных ViewModelProvider.

Примечание: ComponentActivity реализует интерфейс ViewModelStoreOwner и FragmentActivity (родитель AppCompatActivity) наследует реализацию.

Таким образом, и Activity, и Fragment имеют реализацию c для методов интерфейса ViewModelStoreOwner и сохраняют экземпляр viewmodel согласно lifecycle объектов (включая изменения конфигурации).

Поскольку фрагменты принадлежат операции, получают один и тот же экземпляр операции, поэтому использование getActivity() приведет к использованию объекта ViewModelStoreOwner операции. Чтобы разделить объекты между фрагментами, просто используйте экземпляр действия для создания ViewModelProvider, который будет использовать тот же ViewModelStoreOwner во всех фрагментах, следовательно, вернет постоянный объект viewmodel (если он был создан ранее).

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

Наличие Activity, которое делает как можно меньше, уже давно стало «лучшей практикой», поэтому сценарий Activity и Fragment, которым необходим доступ к одному и тому же экземпляру ViewModel, может не быть охваченным многими руководствами.

Но «нет правила без исключения», и ваш сценарий похож на тот, в котором Activity имеет два Fragment, которые должны обмениваться данными.

В этом случае для ViewModel используется область действия Activity, чтобы каждый компонент имел доступ к одному и тому же экземпляру. См. Также раздел «Обмен данными между фрагментами» в обзоре моделей представлений на developer. android .com

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

Я думаю, что вы получаете ошибку не из-за вашего класса ViewModel. Я удалил все коды, кроме конструктора, и просто сохранил простой класс. Работает нормально. Если вы следуете шаблону MVVM, вы можете получить ошибку из-за реализации базы данных или проверить репозиторий.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...