Viewpager與fragment的組合在項目中使用的頻率過高,咱們對Viewpager的兩種的Adapter的處理方式略顯不足增強一下認識。緩存
先簡單看看Fragment的兩種Adapter的使用方式。
都是PagerAdapter的子類。 bash
1:FragmentStatePagerAdapter
2:FragmentPagerAdapter複製代碼
當Viewpager.setAdapter(),Viewpager與PagerAdapter創建雙向的聯繫。
1)Viewpager會擁有pagerAdapter的對象,能getAdapter獲取到當前的Adapter。
2)mAdapter.setViewPagerObserver(new PagerObserver),至此獲得adapter中的註冊測,能向Viewpager傳遞數據。這樣就算綁在一塊兒了。
ide
這是咱們經常使用兩種Adapter的基類。這是一個abstract的,直接繼承他的話我麼須要重寫方法
1)getItemPosition();
//instantiateItem()的返回值將有此函數的返回值進行判斷,是否進行調用。函數
public static final int POSITION_UNCHANGED = -1;
public static final int POSITION_NONE = -2;複製代碼
如若不重寫,默認返回POSITION_UNCHANGED,將不會調用Viewpager的observer.notifit()
所以,調用Adapter.notifyDataSetChanged()將不會出現什麼改變。
佈局
/**ui
/**spa
if(rootView==null){
rootView=inflater.inflate(R.layout.tab_fragment, null);
}
//緩存的rootView須要判斷是否已經被加過parent, 若是有parent須要從parent刪除,要否則會發生這個rootview已經有parent的錯誤。
ViewGroup parent = (ViewGroup) rootView.getParent();
if (parent != null) {
parent.removeView(rootView);
} 複製代碼
這裏重點說明一下:setUserVisibleHint 調用 在全部生命週期以前執行。每次Adapter切換都會調用相應的Fragment的此方法。
思路也就來了。 實現的思路不少種,仔細看這個生命週期,總結規律,這個懶加載也就現實了。3d
`public abstract class LazzyFragment extends Fragment {
//判斷控件是否加載完畢
private boolean isCreateView = false;
//判斷是否已加載過數據
public boolean isLoadData = false;
/**
* 返回layoutView
* @param inflater
* @param container
* @return 初始化佈局文件
*/
public abstract View getView(LayoutInflater inflater, ViewGroup container);
/**
* 初始化控件
*/
public abstract void initViews(View view);
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = getView(inflater, container);
initViews(view);
isCreateView = true;
return view;
}
//注意,此方法再全部生命週期以前調用,不可操做控件
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser && isCreateView && !isLoadData) {
loadData();
}
}
/**
* 加載數據
*/
public void loadData() {
//若是沒有加載過就加載,不然就再也不加載了
if (!isLoadData) {
//加載數據操做
isLoadData = true;
}
}
// 第一次進入ViewPager的時候咱們須要直接加載,由於此時setUserVisibleHint 已經調用過了。
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (getUserVisibleHint())
loadData();
}複製代碼
}`code