1. 程式人生 > >Fragment與Viewpager實現懶載入

Fragment與Viewpager實現懶載入

本文轉載自:http://blog.csdn.net/q844258542/article/details/51525749(非常感謝博主的分享)

專案當中使用到tablayout+viewpager+fragment組合, 也是現在app非常流行的一種設計.

viewpager切換頁面時,讓fragment進行懶載入操作,是比較好的體驗,節省省流量,避免預載入時造成的卡頓現象.

懶載入操作主要使用到fragment 的 setUserVisibleHint() , 及getUserVisibleHint()方法

setUserVisibleHint() 方法在viewpageradapter內部呼叫, 會為fragment 進行賦值, 如果fragment 不可見賦值為false. 反之為true.

getUserVisibleHint() 方法是獲取這個值, 通過fragment 當前是否可見, 來進行載入資料的操作, 這樣就實現了預載入的功能.

  1. package cn.cibn.haokan.ui.categoryList;  
  2. import android.os.Bundle;  
  3. import android.view.LayoutInflater;  
  4. import android.view.View;  
  5. import android.view.ViewGroup;  
  6. import cn.cibn.haokan.ui.base.ImgBaseFragment;  
  7. public
    abstractclass LazyFragment extends ImgBaseFragment{  
  8.      /** 
  9.      * Fragment title 
  10.      */
  11.     public String fragmentTitle;  
  12.     /** 
  13.      * 是否可見狀態 
  14.      */
  15.     privateboolean isVisible;  
  16.     /** 
  17.      * 標誌位,View已經初始化完成。 
  18.      * 2016/04/29 
  19.      * 用isAdded()屬性代替 
  20.      * 2016/05/03 
  21.      * isPrepared還是準一些,isAdded有可能出現onCreateView沒走完但是isAdded了
     
  22.      */
  23.     privateboolean isPrepared;  
  24.     /** 
  25.      * 是否第一次載入 
  26.      */
  27.     privateboolean isFirstLoad = true;  
  28.     @Override
  29.     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {  
  30.         // 若 viewpager 不設定 setOffscreenPageLimit 或設定數量不夠
  31.         // 銷燬的Fragment onCreateView 每次都會執行(但實體類沒有從記憶體銷燬)
  32.         // 導致initData反覆執行,所以這裡註釋掉
  33.         // isFirstLoad = true;
  34.         // 2016/04/29
  35.         // 取消 isFirstLoad = true的註釋 , 因為上述的initData本身就是應該執行的
  36.         // onCreateView執行 證明被移出過FragmentManager initData確實要執行.
  37.         // 如果這裡有資料累加的Bug 請在initViews方法裡初始化您的資料 比如 list.clear();
  38.         isFirstLoad = true;  
  39.         View view = initViews(inflater, container, savedInstanceState);  
  40.         isPrepared = true;  
  41.         lazyLoad();  
  42.         return view;  
  43.     }  
  44.     /** 
  45.      * 如果是與ViewPager一起使用,呼叫的是setUserVisibleHint 
  46.      * 
  47.      * @param isVisibleToUser 是否顯示出來了 
  48.      */
  49.     @Override
  50.     publicvoid setUserVisibleHint(boolean isVisibleToUser) {  
  51.         super.setUserVisibleHint(isVisibleToUser);  
  52.         if (getUserVisibleHint()) {  
  53.             isVisible = true;  
  54.             onVisible();  
  55.         } else {  
  56.             isVisible = false;  
  57.             onInvisible();  
  58.         }  
  59.     }  
  60.     /** 
  61.      * 如果是通過FragmentTransaction的show和hide的方法來控制顯示,呼叫的是onHiddenChanged. 
  62.      * 若是初始就show的Fragment 為了觸發該事件 需要先hide再show 
  63.      * 
  64.      * @param hidden hidden True if the fragment is now hidden, false if it is not 
  65.      *               visible. 
  66.      */
  67.     @Override
  68.     publicvoid onHiddenChanged(boolean hidden) {  
  69.         super.onHiddenChanged(hidden);  
  70.         if (!hidden) {  
  71.             isVisible = true;  
  72.             onVisible();  
  73.         } else {  
  74.             isVisible = false;  
  75.             onInvisible();  
  76.         }  
  77.     }  
  78.     protectedvoid onVisible() {  
  79.         lazyLoad();  
  80.     }  
  81.     protectedvoid onInvisible() {  
  82.     }  
  83.     /** 
  84.      * 要實現延遲載入Fragment內容,需要在 onCreateView 
  85.      * isPrepared = true; 
  86.      */
  87.     protectedvoid lazyLoad() {  
  88.         if (isPrepared && isVisible && isFirstLoad) {  
  89.             isFirstLoad = false;  
  90.             initData();  
  91.         }  
  92.     }  
  93.     protectedabstract View initViews(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState);  
  94.     protectedabstractvoid initData();  
  95. }