一、fragment的生命周期的注意点。
android上使用Fragment已经基本成为了一种趋势。fragment的使用今天就不说了。今天说一下fragment的生命周期的注意点。
fragment的生命周期函数onResume,onPause,setUserVisibleHint
fragment的显示与否,我们基本通过这三个方法来判断。
但是最近发现一些问题。
项目中的需求是:
类似网易新闻的头部tab,可以滑动来切换。这种需求我们基本通过viewpager+fragment实现。
如果现在在TAB4显示的时候需要在界面右下角显示一个按钮,TAB4不显示的时候按钮要消失。
开始我就在TAB4对应的framgent的onResume方法里面add一个button,onPause隐藏这个button,结果发现不行,activity显示的时候button就显示了,activity隐藏的时候button才隐藏。查阅资料发现fragment的onResume和onPause方法调用是在activity的onResume和onPause调用的时候被调用的。那这样的话肯定是不行的。
后来发现了setUserVisibleHint方法。这个方法才是正确标识fragment显示隐藏的方法。
public void setUserVisibleHint(booleanisVisibleToUser) 我们可以通过isVisibleToUser判断fragment是否显示。
到这边基本就大功告成了。但是还有一点小注意点:
setUserVisibleHint方法在activity的onPause,onResume方法中是不会调用的。
二、Fragment中关于actionbar的onCreateOptionsMenu和onOptionsItemSelected的调用注意点
在Activity的调用actionbar的上述方法是完全没有问题的,我们说一下在fragment里面调用这两个方法的注意点,
Fragment是依附于Activity的,不能独立存在,直接嵌套的Activity里面的Fragment我们称为以及Fragment,在这类Framgent里面我们只需要在onCreateView方法中调用setHasOptionsMenu(true);这个设置可以使用menu。
我们就可以放心的使用onCreateOptionsMenu和onOptionsItemSelected这两个方法。
但是有很多时候我们需要在Fragment里面嵌套Fragment,我们称这类为二级Fragment,如果在这类Fragment中使用actionbar的这两个方法,就有问题了,这两个回调方法只能由activity和一级Framgent响应,二级Fragment是无法主动响应的,也就是说二级的Fragment是没有办法主动创建menu的。
有什么办法解决呢???
既然二级是嵌套在一级Fragment中的,那么一级fragment对象肯定持有二级fragment对象的引用,于是我们可以在以及fragment中调用onCreateOptionsMenu和onOptionsItemSelected这两个方法来主动创建和响应menuitem。我们在一级fragment的onOptionsItemSelected方法中主动的调用二级fragment的onOptionsItemSelected方法。这样就可以折中的解决二级fragment无法创建响应actionbar的menu了。
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case DELETE:
//主动调用二级fragment的onOptionsItemSelected
if (fragments != null) {
childFragment.onOptionsItemSelected(item);
}
break;
default:
break;
}
return super.onOptionsItemSelected(item);
}
三、Fragment嵌套时,内部的Fragment无法加载显示?
找了很多资料,开始的时候以为是android系统的问题,后来才知道是自己代码写的不对。具体请看下面的这段话
The definition of getChildFragmentManager()
is:Return a private FragmentManager for placing and managing Fragments inside of this Fragment.
Meanwhile the definition of getFragmentManager()
(or in this case getSupportFragmentManager()
)is:
Return the FragmentManager for interacting with fragments associated with this fragment's activity.
Basically, the difference is that Fragment's now have their own internal FragmentManager
that can handle Fragments. The child FragmentManager is the one that handles Fragments contained within only the Fragment that it was added to. The other FragmentManager is contained within the entire Activity
.
In this case, what I'm guessing is you've added the Fragments to the Activity's FragmentManager. You get the child FragmentManager which doesn't contain what you are looking for. Thus you get the exception because it can't find the Fragment with the given ID because it's in a different FragmentManager.
=============================================
大致的意思就是:getSupportFragmentManager方法返回的是Activity所属的FrgamentManager,而getChildFragmentManager方法返回的是当前Fragment所属的
FragmentManager。当我们在Fragment里面使用getSupportFragmentManager操作嵌套的Fragment,肯定会报错或者页面加载空白,因为加进来的Fragment被
ChildFragmentManager所管理,在SupportFragmentManager找不到该Fragment的。
mSectionsPagerAdapter= new SectionsPagerAdapter(getActivity().getSupportFragmentManager());
在Fragment里面嵌套Fragment的话,不要用上面的那句。。。会在ViewPager中出现Fragment不会加载的情况。。。既ViewPager加载Fragment 空白页的情况。。。。
所以 Fragment里面嵌套Fragment 的话:一定要用getChildFragmentManager();
mSectionsPagerAdapter= new SectionsPagerAdapter(getChildFragmentManager());