繁体   English   中英

用于 Fragment 的 ViewModel 而不是访问 Activity ViewModel?

[英]ViewModel for Fragment instead accessing Activity ViewModel?

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

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

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

  • 您的解决方案在这里!

我会说以上所有这些都违反了很多设计原则,那我该怎么办? 我该如何走出这个烂摊子? 有没有Uncle Bob或其他superhero来帮忙?

PS - 好吧,创建 UML 或其他图表不是我的强项。 对不起。
PPS - 我知道google samples

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

制作一个ViewModel

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

ViewModelProviders.of(getActivity()).get(MyActivityViewModel.class); // Like this in fragment.

&

ViewModelProviders.of(this).get(MyActivityViewModel.class); // Like this in activity.

这将在您的Activityfragment之间共享公共ViewModel


另一个ViewModel会去FirstFragment在你的情况,如果你有你之间共享逻辑ChildFragment

在这里你可以分享ViewModel让我们说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.

尽管如此,我们仍然可以在来自 FirstFragment 的子片段中使用我们的活动级别MyActivityViewModel ,例如:

ViewModelProviders.of(getActivity()).get(MyActivityViewModel.class);

首先,为单个View使用多个ViewModel没有坏处。

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

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

我要做的是将活动的ViewModel分解成更小的部分,并在我的Fragments重用正确的ViewModel ,这样我就不会拥有God ViewModel ,也不会在不同的ViewModel 中使用大致相同的代码。

这是 Jeel Vankhede 给出的答案的更新版本。 还有 Kotlin 的实现也是一样的。

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

以下是您在 Activity 中的操作方法:

ViewModelProvider(this).get(MyActivityViewModel::class.java)

以下是您在 Fragment 中的操作:

ViewModelProvider(requireActivity()).get(MyActivityViewModel::class.java)

为了解决FirstFragment与其子片段共享其视图模型的问题,您可以使用此代码从任何子片段访问FirstFragmentViewModel

    // in ChildFragment1
    val firstFragmentViewModel: FirstFragmentViewModel by viewModels(
        { requireParentFragment() }
    )

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM