Используете LiveData / ViewModel с фрагментами? - PullRequest
0 голосов
/ 06 мая 2020

Сначала я опишу, чего я хочу достичь:

У меня есть действие, содержащее фрагмент. Теперь, на основе некоторого действия, действие вызовет FragmentManager и заменит новый фрагмент того же типа.

В моем классе фрагментов у меня есть связанный ViewModel, который я получаю. Во фрагменте onCreateView () я подписываюсь на компонент LiveData в ViewModel.

Я создаю экземпляры многих из этих фрагментов на протяжении всего времени существования приложения, но только один из них активен в любой момент, как описано выше.

Мой вопрос: гарантировано ли мне, что при вызове getSupportFragmentManager().replace(id, new MyFrag()) он перестанет наблюдать изменения из LiveData во фрагменте, который в данный момент активен (и собирается быть заменен), и скорее new MyFrag() будет только наблюдатель?

Мое второе требование - мне нужно знать, когда фрагмент был прикреплен после вызова replace(), как мне это обеспечить? (обратите внимание, я не хочу отменять onAttach (), я хочу знать это после вызова replace)

Изменить: Я полностью опишу свой вариант использования

Мне нужно, чтобы данные были инициализированы один раз и наблюдались моим фрагментом.

Позвольте мне объяснить:

У меня есть родительская активность, у которой есть ViewModel, которая загружает некоторые данные. Эти данные нужны моему Фрагменту, и они нужны только в первый раз, когда Фрагмент создается. Что я делаю, так это настраиваю наблюдателей в моем фрагменте, которые просто наблюдают за изменениями в LiveData родительской активности. Поэтому сразу после создания фрагмента мне нужно инициализировать эти данные, а только один раз , поэтому я вызываю функцию, которая загружает эти данные в виртуальную машину, связанную с моей родительской активностью. Но поскольку мой фрагмент еще не прикреплен, данные просто теряются, потому что мои наблюдатели только начинают наблюдать, когда фрагмент не только создан, но и прикреплен.

Теперь вы можете сказать, поэтому просто инициализируйте эти данные в Фрагменты конструктора ViewModel, но я не могу этого сделать, потому что это зависит от другого важного фрагмента данных, который есть только у родительской виртуальной машины.

Надеюсь, все понятно, любые указания помогут, спасибо!

1 Ответ

1 голос
/ 06 мая 2020

Вместо того, чтобы получать модель представления и подписываться на нее в onCreate, вы должны сделать это в onCreateView и использовать viewLifecycleOwner в качестве владельца жизненного цикла. Это гарантирует, что при уничтожении представления все наблюдатели будут удалены одновременно.

Если вы используете this (фрагмент) в качестве владельца жизненного цикла, наблюдатели будут удалены только при уничтожении фрагмента. Предполагая, что вы используете задний стек, замена фрагмента не уничтожит его немедленно. Но представление гарантированно будет уничтожено.

Что касается второго вопроса, я действительно не эксперт в жизненном цикле фрагментов, но могли бы вы здесь использовать onCreate или onCreateView? В чем дело?

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