在使用了Google MVP architecture之后,View层以一个动态Fragment的形式独立于Activity。在原本使用Activity作为View层时,如果需要内嵌多个动态Fragment,例如常见的ViewPager,我们可以使用Activity的FragmentManager来管理他们。而在Google MVP模式下,这就变成了一个View层的主Fragment嵌套许多子Fragment。在这时,我们应相应的用View层Fragment的FragmentManager来管理子Fragment。而这时,获取FragmentManager的方法应为getChildFragmentManager()
,注意这里容易写错成getActivity().getSupportFragmentManager()
,如果使用后者,则获得的是外层Activity的FragmentManager,此时是不符合逻辑的。
例如PKU Helper 3.0+版本的树洞页面,HoleFragment为整体的View层,其中只包含一个ViewPager。ViewPager包含树洞
和关注
两个HoleListFragment。
在HoleFragment中,有如下setupPager()
方法,在onCreateView()
中被调用,负责初始化ViewPager。
1 | private void setupPager() { |
如果按以上代码编写,在重加载HoleActivity时,会弹出NullPointer异常。追根溯源,是重加载时初始化的Fragment并非是15、16行中与Presenter绑定的Fragment,即他们是不同的实例,这在debug模式中查看内存地址可以得到。于是在Presenter调用View层,即子Fragment中的方法时,调用的是未初始化的Fragment,其又含有未赋值的成员变量,故在调用这些成员变量时,触发了NullPointer异常。
正确的方法是,将上述代码中全部的getActivity().getSupportFragmentManager()
替换为getChildFragmentManager()
,这时我们才获取的是正确的FragmentManager。
在上图中我们可以更加清晰的看到,负责管理ViewPager中的两个子Fragment的应当是FragmentManager#2
,所以用getChildFragmentManager()
才是正确的做法。