ViewModel for Fragment而不是访问Activity ViewModel?

Yur*_*sap 14 android mvvm android-fragments kotlin android-architecture-components

问题非常简单.问题在于使用ViewModels,LiveData和其他相关的生命周期感知的arch方法.
我有一个带有NavDrawer的Activity,可以在里面切换片段.
而且我有一个案例,当屏幕上同时出现两个片段时 - 这将是主要的痛苦.One Fragment有一个嵌套的ViewPager Fragments(不要问为什么).另一个片段只是在用户执行某些操作时从第一个获取信息.这只是通过共享活动视图模型来实现的.但是应用程序本身有很多业务逻辑,随着视图模型越来越大,视图模型越来越大.
我想问的是 - 不是收据或规则如何解决这个问题,或者可能是如何通过修复整个项目结构来解决这个问题.我想问一下建议如何将android.arch.lifecycle样式中的MVVM方法应用于我的用例.
我没有看到更复杂的东西,只是在Fragments之间共享Activity ViewModel.但很常见,那不是治愈方法. 在此输入图像描述

你在这里可以看到什么 - 实际上是一团糟.关键是所有人都在分享ActivityViewModel.来自FirstFragment的连接(聚合)意味着ViewPager内部FirstFragment正在启动,ChildFragments并且它们也在使用相同的ActivityViewModel(杀死我).因此,每个人都在使用一个共享的ViewModel.
我的建议是为每个Layer添加一个ViewModel.因此,Activity/Fragments/ChildFragments拥有自己的ViewModels.但是这里出现了什么 - 我们应该如何沟通呢?
可能的解决方案 :

  • 每个组件有两个ViewModel.一个ViewModel将处理/委托业务逻辑,另一个将进行通信.每个组件有两个视图模型 - 不太好,是吗?
  • 有旧的界面(请不!)
  • 其他解决方法 - 比如DB/SharedPrefs/Realm改变了监听器和事件总线(我太老了:()).

  • 你的解决方案!

我会说以上所有都打破了很多设计原则,所以我该怎么办?我该怎么走出这个烂摊子?这里有什么Uncle Bob或另一个superhero可以提供帮助吗?

PS - 好吧,创建UML或其他图表不是我的强项.对不起.
PPS - 我知道谷歌 样本.

Jee*_*ede 14

我建议您可以ViewModel为整个用例处理两个。

做一个 ViewModel

假设MyActivityViewModel要处理与活动级别相关的所有逻辑。因此,如果任何片段逻辑与您的活动直接相关,请在ViewModel下面分享您的喜欢:

ViewModelProviders.of(getActivity()).get(MyActivityViewModel.class); // Like this in fragment.
Run Code Online (Sandbox Code Playgroud)

&

ViewModelProviders.of(this).get(MyActivityViewModel.class); // Like this in activity.
Run Code Online (Sandbox Code Playgroud)

This will share common ViewModel between your activity and fragment.


Another ViewModel would go for FirstFragment in your case if you have to share logic between your ChildFragment :

Here you can share ViewModel let's say FragmentViewModel like below:

ViewModelProviders.of(this).get(FragmentViewModel.class); // Like this in FirstFragment which is having view pager.
Run Code Online (Sandbox Code Playgroud)

&

ViewModelProviders.of(getParentFragment()).get(FragmentViewModel.class); // Like this in View pager fragments, getParentFragment() is First fragment in our case.
Run Code Online (Sandbox Code Playgroud)

Although, we can still use our activity level MyActivityViewModel in our child fragments from FirstFragment like :

ViewModelProviders.of(getActivity()).get(MyActivityViewModel.class);
Run Code Online (Sandbox Code Playgroud)


Nag*_*obi 7

首先出现的是在不存在损害 ViewModel的一个单一 视图

我会考虑我的ViewModel就像获取和操作什么样的数据,并以某种方式对它们进行分组,这似乎很自然。

对于您的情况,如果片段和活动的逻辑非常相似,我认为您可以使用单个ViewModel,但我会避免这样做。

我会做的是打破了活动的ViewModel成较小的部分,并重新使用正确ViewModel的我Fragments,这样我就没有上帝视图模型,也大致在不同的同一代码视图模型的。


Das*_*esh 5

这是 Jeel Vankhede 给出的答案的更新版本。以及同样的 Kotlin 实现。

由于 ViewModelProviders 已被弃用,我们现在必须使用 ViewModelProvider。

以下是在 Activity 中执行此操作的方法:

ViewModelProvider(this).get(MyActivityViewModel::class.java)
Run Code Online (Sandbox Code Playgroud)

以下是在 Fragment 中的操作方法:

ViewModelProvider(requireActivity()).get(MyActivityViewModel::class.java)
Run Code Online (Sandbox Code Playgroud)