Android MVP与Dagger 2 - 含多个Fragment的Activity

9

我一直在查看使用Dagger 2的MVP的Google Android架构示例:

https://github.com/googlesamples/android-architecture/blob/todo-mvp-dagger/todoapp/app/src/main/java/com/example/android/architecture/blueprints/todoapp/tasks/TasksActivity.java

但是,这个例子相当简单 - 每个Activity只有一个Fragment,并且Dagger Component在Activity中构建,在Fragment中使用它来为Fragment注入Presenter。我尝试构建这个示例,向其中添加多个Fragment并在它们之间导航。由于每个Fragment都有自己的Presenter,因此我将Dagger Component的构建移至Fragment中。现在我有: - FragmentCallback(提供加载fragment1和fragment2方法的接口) - Activity(实现FragmentCallback) - Fragment1(实现视图接口) - Fragment1Contract(定义视图和Presenter接口) - Fragment1Presenter(实现Presenter接口) - Fragment1Component(注入Fragment1) - Fragment1Module(提供视图和Presenter) - Fragment2 - Fragment2Contract(定义视图和Presenter接口) - Fragment2Presenter(实现Presenter接口) - Fragment2Component(注入Fragment2) - Fragment2Module(提供视图和Presenter)
Activity几乎什么也不做,只是加载第一个Fragment并实现FragmentCallback接口,这样视图就可以使用它来切换到另一个Fragment。
第一个片段有一个按钮,使用 FragmentCallback 加载第二个片段 - 片段通过将 Activity 强制转换获得 FragmentCallback。
public void onAttach(Context context) {
    super.onAttach(context);
    callback = (FragmentCallback) context;
}

我这样做是否合理?虽然使用MVP使代码看起来很清晰,但关于dagger组件和模块方面,我是否遗漏了什么?
谢谢。
更新
我通过为活动创建一个组件和模块来改善了我的情况。每个片段仍然构建Dagger上下文,但我不再在Presenter构造函数中注入视图(片段)。当片段构建上下文并注入自身(以便具有Presenter)时,它会调用presenter.init(this),以使Presenter现在具有视图。
这样可以很好地减少类的数量,下一步将尝试仅在活动中构建组件,并使片段使用此组件来注入自身(无需构建新组件)。

1
是的,你差不多走对路了。 - Javed Salat
差不多?能详细说明一下吗? - prule
@prule “我这里走对了吗?” 目前有什么问题吗?如果没有,那你就走在正确的轨道上了。很难对这样的问题给出不带个人意见的答案。 - Dmitry Zaytsev
@DmitryZaitsev 我在这个简单的设置中没有遇到任何问题,但是为每个片段创建模块和组件似乎有些过度...我想知道是否可能为活动创建一个组件(覆盖多个片段)甚至为整个应用程序创建一个组件。 - prule
@prule 我和你一样追踪这个问题。我尝试了不同的方法,但这是对我来说最方便的方式。 - Olkunmustafa
显示剩余2条评论
1个回答

0

你肯定走在了正确的道路上。

我建议你不要在Activity中使用单个组件,而是为每个Fragment实例化一个单独的组件(即使这些组件是相同的)。这种方法有两个好处:

  • Fragments本身(以及组件可能缓存的对象)不会将其与Activity和其他Fragments耦合
  • 允许更细粒度地使用作用域(如果您需要的话)

离题:

我写了一篇关于为什么Android中的活动不是UI元素的博客文章。看看吧,如果你觉得它有意义,那么就有一个链接到MVP的替代实现 :)


我不能说他的实现方式是最好的,但我可以很容易地指出一个缺点:你不能在Activity中注入Fragment的Presenter,必须使用接口来与Fragment通信。例如,假设你想在重新选择BottomNavigationView项目时将列表滚动到顶部。如果你有访问Fragment的Presenter,那么这将非常容易,但现在你必须使用接口将命令发送到Fragment。 - Farid

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接