ViewModel for Fragment вместо доступа к Activity ViewModel?
Проблема довольно проста. Вопрос в том, что касается использования ViewModels, LiveData и других связанных с Lifecycle арочных подходов.
У меня есть активность с NavDrawer, который переключает фрагменты внутри.
А также у меня есть случай, когда на экране одновременно присутствуют два фрагмента - это будет основной болью. Один фрагмент имеет ViewPager с вложенными Fragments
(не спрашивайте почему). Другой фрагмент просто получает информацию от первого, когда пользователь выполняет некоторые действия. Это достигается просто путем совместного использования активности viewmodel. Но само приложение имеет много бизнес-логики, и по мере продвижения модель представления становится все больше и больше.
То, что я хочу спросить - не квитанция или правила, как это исправить, или, может быть, как преодолеть это, исправив всю структуру проекта. Я хочу попросить совета, как я могу применить подход MVVM в стиле android.arch.lifecycle для моего варианта использования.
Я не видел ничего более сложного, чем просто разделение Activity ViewModel между фрагментами. Но часто это не лекарство. ![enter image description here]()
То, что вы можете увидеть здесь - на самом деле беспорядок. Дело в том, что все делят ActivityViewModel
. Соединения (агрегация) из FirstFragment означают, что ViewPager
внутри FirstFragment
инициирует ChildFragments
и они также работают с тем же ActivityViewModel
(убей меня). В результате все работают с одной общей моделью ViewModel.
Мое предложение состоит в том, чтобы добавить ViewModel для каждого слоя. Так что Activity/Fragments/ChildFragments имеют свои собственные ViewModels. Но что здесь появляется - как нам тогда общаться?
Возможные решения:
Я скажу, что все вышеперечисленное нарушает многие принципы дизайна, так что мне делать? Как я должен выйти из этого беспорядка? Есть ли здесь Uncle Bob
или другой superhero
чтобы помочь?
PS - Ну, создание UML или других диаграмм - не моя сильная сторона. Простите за это.
PPS - мне известны образцы Google.
Ответы
Ответ 1
Во-первых, нет никакого вреда в наличии нескольких ViewModel
для одного Вид.
Я бы подумал о моем ViewModel, как то, что данные получают и манипулируют, и группировать их таким образом, что кажется естественным.
В вашем случае, если фрагменты и логика активности очень похожи, я думаю, вы можете пойти с одним ViewModel
, но я бы этого избежал.
Что бы я сделал, это разбить активность ViewModel
на более мелкие части и повторно использовать правильный ViewModel
в моем Fragments
, чтобы у меня не было God ViewModel, а не грубо тот же код в разных ViewModel.
Ответ 2
То, что я хотел бы предложить, вы можете обработать два ViewModel
для всего вашего варианта использования.
Сделай одну ViewModel
Допустим, скажем, MyActivityViewModel
для обработки всей логики, связанной с уровнем активности. Итак, если какая-либо фрагментная логика напрямую связана с вашей деятельностью, то поделитесь вашей ViewModel
как ViewModel
ниже:
ViewModelProviders.of(getActivity()).get(MyActivityViewModel.class); // Like this in fragment.
&
ViewModelProviders.of(this).get(MyActivityViewModel.class); // Like this in activity.
Это разделит общую ViewModel
между вашей деятельностью и фрагментом.
Другая ViewModel
будет использовать FirstFragment
в вашем случае, если вам придется делиться логикой между ChildFragment
:
Здесь вы можете поделиться ViewModel
скажем, FragmentViewModel
как FragmentViewModel
ниже:
ViewModelProviders.of(this).get(FragmentViewModel.class); // Like this in FirstFragment which is having view pager.
&
ViewModelProviders.of(getParentFragment()).get(FragmentViewModel.class); // Like this in View pager fragments, getParentFragment() is First fragment in our case.
Хотя мы все еще можем использовать наш уровень активности MyActivityViewModel
в наших дочерних фрагментах из FirstFragment, таких как:
ViewModelProviders.of(getActivity()).get(MyActivityViewModel.class);