項目中經常會用到ViewPager+Fragment組合,然而,有一個很讓人頭疼的問題就是,去加載數據的時候由於ViewPager的內部機制所限制,所以它會默認至少預加載一個。
1、既然說是ViewPager的內部機制,那么我們可不可以設置ViewPager的預加載為0?如下:
vp.setOffscreenPageLimit(0);
No,結果發現根本行不通。。。查看源碼:
private static final int DEFAULT_OFFSCREEN_PAGES = 1; /** * Set the number of pages that should be retained to either side of the * current page in the view hierarchy in an idle state. Pages beyond this * limit will be recreated from the adapter when needed. * * <p>This is offered as an optimization. If you know in advance the number * of pages you will need to support or have lazy-loading mechanisms in place * on your pages, tweaking this setting can have benefits in perceived smoothness * of paging animations and interaction. If you have a small number of pages (3-4) * that you can keep active all at once, less time will be spent in layout for * newly created view subtrees as the user pages back and forth.</p> * * <p>You should keep this limit low, especially if your pages have complex layouts. * This setting defaults to 1.</p> * * @param limit How many pages will be kept offscreen in an idle state. */ 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(); } }
所以即使你設置為0,還是會設置默認值1,所以這個方法是行不通的。
2、Fragment里面有個setUserVisibleHint(boolean isVisibleToUser)方法,所以考慮在此去處理數據。
public class LazyFragment extends Fragment { protected PullToRefreshListView mPullToRefreshListView; protected EmptyLayout mEmptyLayout; protected ListView mListView; protected int maxId = 0; //標志位,標志已經初始化完成 protected boolean isInit = false; //是否已被加載過一次,第二次不再去請求數據 protected boolean mHasLoadedOnce; private View view; @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { view = inflater.inflate(R.layout.activity_common_list, null); initView(view); return view; } public void initView(View view) { mPullToRefreshListView = (PullToRefreshListView) view.findViewById(R.id.pull_refresh_list); mEmptyLayout = (EmptyLayout) view.findViewById(R.id.error_layout); isInit = true; isCanLoadData(); } @Override public void setUserVisibleHint(boolean isVisibleToUser) { super.setUserVisibleHint(isVisibleToUser); isCanLoadData(); } /** * 禁止預加載 */ private void isCanLoadData() { if (!isInit) { return; } if (getUserVisibleHint() && !mHasLoadedOnce) { loadData(); } } protected void loadData() { //數據加載成功后
mHasLoadedOnce = true;
}
}
在loadData()中加載數據,在數據加載成功之后將mHasLoadedOnce置為true即可。以上完美解決因為Fragment的懶加載導致的,比如:預先請求服務器接口,造成服務器額外壓力等問題~
By LiYing