首页 文章

ViewModel for Fragment而不是访问Activity ViewModel?

提问于
浏览
11

问题非常简单 . 问题在于使用ViewModels,LiveData和其他相关的Lifecycle感知的arch方法 .
我有一个带有NavDrawer的Activity,可以在里面切换片段 .
而且我有一个案例,当屏幕上同时出现两个片段时 - 这将是主要的痛苦 . One Fragment有一个嵌套 Fragmentsdon't ask why )的ViewPager . 另一个片段只是在用户执行某些操作时从第一个获取信息 . 这只是通过共享活动视图模型来实现的 . 但是应用程序本身有很多业务逻辑,随着视图模型越来越大,视图模型越来越大 .
我想问的是 - 不是收据或规则如何解决这个问题,或者可能是如何通过修复整个项目结构来解决这个问题 . 我想问一下建议如何将android.arch.lifecycle样式中的MVVM方法应用于我的用例 .
我没有办法治愈 .
enter image description here

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

  • 每个组件有两个ViewModel . 一个ViewModel将处理/委托业务逻辑,另一个将进行通信 . Two viewmodels per component - not so good, yeah?

  • 具有旧方式界面( please no!

  • 其他解决方法 - 比如DB / SharedPrefs / Realm更改侦听器和事件总线( I'm too old for this :( ) .

  • Your solution here!

我会说以上所有都打破了很多设计原则,所以我该怎么办?我该怎么走出这个烂摊子?有没有 Uncle Bob 或其他 superhero 来帮助?

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

2 回答

  • 0

    首先,单个 View 有多个 ViewModel 是没有害处的 .

    我会想到我的 ViewModel 喜欢什么样的数据正在获取和操纵,并以某种方式对它们进行分组,这看起来很自然 .

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

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

  • 3

    What i would suggest 你能做的就是为你的整个用例处理两个 ViewModel .

    制作一个 ViewModel

    假设 MyActivityViewModel 处理与 activity 级相关的所有逻辑 . 那么,如果任何 fragment 逻辑与您的 activity 直接相关,那么请分享您的 ViewModel ,如下所示:

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

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

    这将在您的 activityfragment 之间共享 ViewModel .


    如果您必须在 ChildFragment 之间共享逻辑,那么另一个 ViewModel 将用于 FirstFragment

    在这里你可以分享 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);
    

相关问题