我有一个MainActivity,它包含经典的抽屉布局,单击抽屉项目并将片段加载到主容器中。在app load上,我的“MapFragment”被加载到容器中。这个片段包含一个BottomSheet,其中包含一个ViewPager
,其中包含2个片段。
如果我加载应用程序并离开MapFragment,请说“SupportFragment”,通过单击抽屉项,该片段将加载到容器中。如果我然后导航回MapFragment,则BottomSheet ViewPager
中包含的片段中的所有视图现在都为空。
为了澄清,ViewPager
中的片段不为空,但所有视图都是。
目前,使用以下代码在MapFragment的onCreate()
中设置ViewPager:
mBottomSheetViewPagerAdapter = new BottomSheetViewPagerAdapter(((MainActivity)getActivity()).getSupportFragmentManager());
mFirstFragment = new FirstFragment();
mFirstFragment.setListener(new FirstFragmentListener() {
//...listeners
});
mSecondFragment = new SecondFragment();
mSecondFragment.setListener(new SecondFragmentListener() {
//...listeners
});
mBottomSheetViewPagerAdapter.add(mFirstFragment);
mBottomSheetViewPagerAdapter.add(mSecondFragment);
mViewPager.setAdapter(mBottomSheetViewPagerAdapter);
mTabLayout.setupWithViewPager(mViewPager);
为什么这些观点可能为空?
编辑:所以我找到了一些相当有趣的东西。我将日志语句添加到父“MapFragment”和ViewPager
(“FirstFragment”)中的一个片段的生命周期方法中。我注意到,在第一次启动MapFragment时,我会看到它的生命周期方法打印出来,然后是ViewPager
中的子片段。当我导航离开时,将调用MapFragment的onPause()
和onStop()
,但是ViewPager
中的子片段没有打印任何内容。当我通过单击抽屉中的选项导航回MapFragment时,我看到了MapFragment中的启动生命周期方法,但没有看到ViewPager
中的子片段。
如果我重构ViewPager
中的子片段以使用本机片段而不是支持片段,然后将ViewPager
适配器从FragmentPagerAdapter的v13版本扩展,那么我会传入{ {1}}实例化我的适配器时:getChildFragmentManager
这具有来自正在运行的mBottomSheetViewPagerAdapter = new BottomSheetViewPagerAdapter(getChildFragmentManager());
中的子片段的缺失生命周期方法的有趣效果,因此打印了它们相应的日志语句。为了说明所有这些,这里总结了在启动应用程序时导航到logcat的内容,导航到不同的片段,然后导航回原始的片段:
使用支持片段:
ViewPager
使用原生片段
//App launched, default MapFragment loaded
MapFragment onCreate()
MapFragment onCreateView()
MapFragment onStart()
MapFragment onResume()
FirstFragment onCreate() called
FirstFragment onCreateView() called.
FirstFragment onStart() called.
FirstFragment onResume() called.
//Navigate to another fragment
MapFragment onPause()
MapFragment onStop()
//Use the drawer to navigate back to the MapFragment
MapFragment onCreateView()
MapFragment onStart()
MapFragment onResume()
但是,即使明确地看到第二次调用子片段onCreateView(),如果我尝试访问任何视图(在这种情况下,调用一个调用//App launched, default MapFragment loaded
MapFragment onCreate()
MapFragment onCreateView()
MapFragment onStart()
MapFragment onResume()
FirstFragment onCreate() called
FirstFragment onCreateView() called.
FirstFragment onStart() called.
FirstFragment onResume() called.
//Navigate to another fragment
FirstFragment onPause() called.
MapFragment onPause()
FirstFragment onStop() called
MapFragment onStop()
//Use the drawer to navigate back to the MapFragment
MapFragment onCreateView()
FirstFragment onCreateView() called.
MapFragment onStart()
FirstFragment onStart() called.
MapFragment onResume()
FirstFragment onResume() called.
的方法一个setFocusable()
),我得到一个NPE。