如果您使用一个 Activity 来托管多个 Fragment,并且您还使用 Dagger 2 来注入您需要的 Presenter,您可以将每个 Presenter 直接注入每个 Fragment。
我的用例故事
自从我发现 Android jetpack Navigation Component 几个月后,我开始做一个架构项目,我开始将我所有的应用程序视图迁移到这种模式中。
所以,我在做这个过程时遇到了很多重构,我当时不知道如何处理这种情况。
由于我从一开始就使用 Dagger 2 将我的演示者注入到我的活动中,所以这样做不会有太大变化,但使用 Fragments。
我遇到了同一个存储库来检查架构应该如何与 Fragments 一起使用,如果您小时候只有 1 个 Fragment,这确实是在主机 Activity 中进行演示者实例化的好方法。
问题是,如果我需要在一个主机 Activity 中有多个片段,我应该为每个演示者创建一个实例,并将其通过每个片段中的 FragmentManager 传递,我认为这不是我所看到的,因为它添加了来自主持人活动的演示者。
这会导致一种情况,在我的主机活动中为所有演示者提供多个实例,以及一些接口来处理作业/视图的分离(如果需要)。
使用多个片段执行此操作的一种简单方法是不考虑主机活动并将演示者注入每个片段本身。
由于使用 Dagger 执行此操作,它使注入更清洁。
看一个简单的例子
class MainMenuActivity : BaseActivity(){
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
inflateMainFragment(savedInstanceState)
}
override fun getLayout(): Int {
return R.layout.activity_main_menu
}
fun inflateMainFragment(savedInstanceState: Bundle?){
if (savedInstanceState == null) {
val fragment = MainMenuFragment()
supportFragmentManager
.beginTransaction()
.add(R.id.nav_host_fragment, fragment)
.commit()
}
}
}
正如你所看到的,在这里我没有任何我的导航应该需要的任何演示者的实例化。相反,我只是在每个片段中注入我需要的每个演示者
class MapsFragment: BaseMapFragment(), MapContract.MapView {
private lateinit var mMap: GoogleMap
@Inject
lateinit var presenter: MapsPresenter
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_paseo,container,false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
(requireActivity().application as YawpApplication).getAppComponent()?.inject(this)
presenter.attachView(this)
setupToolbar()
setupMap()
}
}
并且利用 Fragments 生命周期,您可以在onDestroyView()方法中分离所有 Fragments 视图,并在垃圾收集器运行时节省一些内存空间。
override fun onDestroyView() {
super.onDestroyView()
presenter.detachView()
presenter.detachJob()
}
我在官方 google repo 中发现了一个帮助我更好地理解它的问题。
你可以在这里查看