使用ViewPager的時候,會發(fā)現(xiàn)當(dāng)前Fragment即使不可見,也會執(zhí)行Fragment的onResume方法。
原因分析:
這是ViewPager為了保證滑動的平滑,做的提前加載。
變量為mOffscreenPageLimit默認(rèn)值為1.
ViewPager可以設(shè)置提前加載幾頁。
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();
}
}
但是不能設(shè)置為0,所以默認(rèn)最少加載一頁的。
FragmentPagerAdapter
FragmentStatePagerAdapter的InstantiateItem方法都會調(diào)用
Fragment的setUserVisibleHint(false)方法。
所以在首次啟動的時候,第一個Fragment和第二個Fragment由于默認(rèn)需要初始化一個頁面,都會調(diào)用setUserVisibleHint(false)方法。
同時設(shè)置當(dāng)前要顯示的Fragment的時候回調(diào)
setPrimaryItem 方法會調(diào)用setUserVisibleHint(true)方法。
所以可以把setUserVisibleHint當(dāng)成Fragment顯示的回調(diào)。
由于viewpager的預(yù)加載,onResume等生命周期已經(jīng)走完,但是每次現(xiàn)實都會調(diào)用一次setUserVisibleHint(雖然會多次調(diào)用setPrimaryItem,但是由于有current!=object的判斷,所以只會走一次setUserVisibleHint(true))
在onResume的時候,如果getUserVisibleHint的值是false,不一定不是當(dāng)前顯示,如果為true就一定是當(dāng)前顯示的Fragment
后記
getUserVisibleHint返回的是mUserVisibleHint 的值,這個值默認(rèn)為true,如果沒有人更改會一直是true,對于不是由viewpager加載管理的情況下,會存在Fragment已經(jīng)被移除,但是mUserVisibleHint為true的情況,需要謹(jǐn)慎對待。