ViewPager+ Fragment結合的setUserVisibleHint()呼叫時機
最近的專案使用到了ViewPager + Fragment的模式,要求在每次Fragment獲取顯示的時候來重新整理資料,該專案下ViewPager有5個子fragment,在onCreateView及fragment的setUserVisibleHint(bool isVisibleToUser)中的isVisibleToUser為true的時候重新整理資料的時候出現數據多次重新整理的情況,因此對ViewPage + Fragment的生命週期做了研究。
專案佈局最頂層5個button,主體是ViewPager+fragment, 可以通過點選button直接跳轉到對應的fragment,也可以通過左右滑動來進行相鄰跳轉。
為了研究多個fragment的生命週期,加入列印如下:
@Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { Slog.i("onCreateView 3"); View view = inflater.inflate(R.layout.my_police_events_fragment, container, false); return view; } @Override public void setUserVisibleHint(boolean isVisibleToUser) { Slog.i("setUserVisibleHint 3 " + isVisibleToUser); super.setUserVisibleHint(isVisibleToUser); } @Override public void onDestroyView() { Slog.i("onDestroyView 3 "); super.onDestroyView(); }
1. 第一次進入該activity,fragment1被選中,列印如下:
第一次進入
setUserVisibleHint 1 false
setUserVisibleHint 2 false
setUserVisibleHint 1 true
onCreateView 1
onCreateView 2
建立了fragment1和fragment2, 且fragment1中的setUserVisibleHint引數為true
2. 從fragment1切換到fragment2,fragment2被選中,列印如下:
從1--->2 setUserVisibleHint 3 false setUserVisibleHint 1 false setUserVisibleHint 2 true onCreateView 3
建立了fragment3,且fragment2中的setUserVisibleHint引數為true
3.從fragment2切換到fragment3,fragment3被選中,列印如下:
從2--->3
setUserVisibleHint 4 false
setUserVisibleHint 2 false
setUserVisibleHint 3 true
onDestroyView 1
onCreateView 4
建立了fragment4,銷燬了fragment1,且fragment3中的setUserVisibleHint引數為true
4. 後面滑動的過程日誌列印如下:
從3--->2
setUserVisibleHint 1 false
setUserVisibleHint 3 false
setUserVisibleHint 2 true
onCreateView 1
onDestroyView 4
從2--->3
setUserVisibleHint 4 false
setUserVisibleHint 2 false
setUserVisibleHint 3 true
onDestroyView 1
onCreateView 4
從3--->4
setUserVisibleHint 5 false
setUserVisibleHint 3 false
setUserVisibleHint 4 true
onDestroyView 2
onCreateView 5
從4--->5
setUserVisibleHint 4 false
setUserVisibleHint 5 true
onDestroyView 3
猜測:通過以上日誌,可以發現,不論fragment如何變化,首先被選中的fragment會呼叫引數為true的setUserVisibleHint方法,被選中的fragment與相鄰的fragment的狀態肯定是onCreate的狀態(如果未create就呼叫onCreateView,如果已經是onCreate的狀態不呼叫),相鄰的fragment會呼叫引數為false的setUserVisibleHint方法,其他的fragment是處於onDestroy的狀態。
5. 為了驗證我們的猜想,將不再採用相鄰滑動的方式,採用button點選跳轉的方式來檢驗fragment的生命週期。相關列印如下:
從5--->2
setUserVisibleHint 2 false
setUserVisibleHint 1 false
setUserVisibleHint 3 false
setUserVisibleHint 5 false
setUserVisibleHint 2 true
onCreateView 2
onCreateView 1
onCreateView 3
onDestroyView 4
onDestroyView 5
從2--->4
setUserVisibleHint 4 false
setUserVisibleHint 5 false
setUserVisibleHint 2 false
setUserVisibleHint 4 true
onCreateView 4
onCreateView 5
onDestroyView 2
onDestroyView 1
總結:可以看到,不管fragment如何變化,都是按照上面的規則進行變動的,知道了fragment的生命週期,那麼就可以選擇在合適的時期對我們的資料進行處理了,避免出現數據未載入或者多次載入的情況了。
Google預載入相鄰的fragment是為了滑動更加流暢,給使用者更佳的體驗感。