ViewPager默認的情況是要進行預加載的,這麼做是爲了保證滑動的流暢性。但有時候我們需要在滑動到該頁面的時候再進行加載,網上有好多人說利用
ViewPager.setOffscreenPageLimit(int limit);
然而這個方法並不起作用
正確的方法應該是利用兩個方法 void setUserVisibleHint(boolean isVisibleToUser)、boolean getUserVisibleHint()來判斷當前的fragment是否可見。
經過測試 setUserVisibleHint(boolean isVisibleToUser)方會在在 onCreate() 調用後,onCreateView()調用前執行。
在此構建一個通用 fragment,並設置boolean類型的isVisible來判斷 fragment 是否可見。
import android.support.v4.app.ListFragment;
public abstract class LazyListFragment extends ListFragment {
// 當前可見標識
protected boolean isVisible;
/**
* 在這裏實現Fragment數據的緩加載
* @param isVisibleToUser
*/
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if(getUserVisibleHint()) {
isVisible = true;
onVisible();
} else {
isVisible = false;
onInvisible();
}
}
protected void onVisible(){
lazyLoad();
}
/**
*
* 當前可見時執行的函數
*/
protected abstract void lazyLoad();
protected void onInvisible(){
}
}
讓 ViewPager 裏面的fragment都繼承 LazyListFragment,我寫了兩個 fragment(分別起名爲“娛樂”和“體育”),執行後查看 log 信息如下:
可以看到 ViewPager 默認啓動了兩個 fragment,但是隻有當前可見的“娛樂” fragment 調用了 setUserVisibleHint() 方法,並設置當前可見狀態爲 true
還有一些童鞋可能測試後發現 fragment 沒有調用setUserVisibleHint(),這是因爲該方法只適用於繼承了FragmentPagerAdapter 的Adapter,而繼承了 FragmentStatePagerAdapter 的Adapter不會調用 fragment 的setUserVisibleHint(),具體原因還有待查實,如有大神知道,還請不吝賜教。
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
最近學習到一個新的適配方法,適用於FragmentPagerAdapter以及FragmentStatePagerAdapter,代碼如下:
/**
* Created by lzn on 2016/7/13.
*/
public abstract class BasePageFragment extends ListFragment {
protected boolean isViewInitiated;
protected boolean isVisibleToUser;
protected boolean isDataInitiated;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
isViewInitiated = true;
prepareFetchData();
}
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
this.isVisibleToUser = isVisibleToUser;
prepareFetchData();
}
public abstract void fetchData();
public boolean prepareFetchData() {
return prepareFetchData(false);
}
private boolean prepareFetchData(boolean forceUpdate) {
if (isVisibleToUser && isViewInitiated && (!isDataInitiated || forceUpdate)) {
fetchData();
isDataInitiated = true;
return true;
}
return false;
}
}
ViewPager 裏的 ListFragment 可以繼承這個基類,重寫 fetchData() 即可。關於上面的一種方法爲何在FragmentStatePagerAdapter 中失效,等有空我再查實吧!當然如果有小夥伴知道,還請留言學習。