使用ViewPager的时候,会发现当前Fragment即使不可见,也会执行Fragment的onResume方法。
原因分析:
这是ViewPager为了保证滑动的平滑,做的提前加载。
变量为mOffscreenPageLimit默认值为1.
ViewPager可以设置提前加载几页。
ViewPager. setOffscreenPageLimit()
private static final intDEFAULT_OFFSCREEN_PAGES = 1;
...
public void setOffscreenPageLimit(int limit) {
if (limit < DEFAULT_OFFSCREEN_PAGES) {
Log.w(TAG, "Requested offscreen page limit " + limit + " too small; defaulting to " +
DEFAULT_OFFSCREEN_PAGES);
limit = DEFAULT_OFFSCREEN_PAGES;
}
if (limit != mOffscreenPageLimit) {
mOffscreenPageLimit = limit;
populate();
}
}
但是不能设置为0,所以默认最少加载一页的。
FragmentPagerAdapter
FragmentStatePagerAdapter的InstantiateItem方法都会调用
Fragment的setUserVisibleHint(false)方法。
所以在首次启动的时候,第一个Fragment和第二个Fragment由于默认需要初始化一个页面,都会调用setUserVisibleHint(false)方法。
同时设置当前要显示的Fragment的时候回调
setPrimaryItem 方法会调用setUserVisibleHint(true)方法。
所以可以把setUserVisibleHint当成Fragment显示的回调。
由于viewpager的预加载,onResume等生命周期已经走完,但是每次现实都会调用一次setUserVisibleHint(虽然会多次调用setPrimaryItem,但是由于有current!=object的判断,所以只会走一次setUserVisibleHint(true))
在onResume的时候,如果getUserVisibleHint的值是false,不一定不是当前显示,如果为true就一定是当前显示的Fragment
后记
getUserVisibleHint返回的是mUserVisibleHint 的值,这个值默认为true,如果没有人更改会一直是true,对于不是由viewpager加载管理的情况下,会存在Fragment已经被移除,但是mUserVisibleHint为true的情况,需要谨慎对待。