Fragment结合ViewPager之懒加载
什么是懶加載?為什么要用懶加載?###
1、什么是懶加載
懶加載就是當ViewPager和Fragment結合在一起使用時,Fragment呈現在用戶面前時才加載數據,當其從未被呈現在用戶面前時,不會執行加載數據的代碼。這就是我所理解的懶加載。
2、為什么要用懶加載
ViewPager默認會預加載下一頁,對于某些重量級的Fragment來說無疑會造成很大的開銷,當然了,如果對于你來說這些開銷是必要的,也不必無腦用懶加載。
背景簡介
很多時候我們都會將ViewPager和Fragment結合在一起使用,因為Android給我們提供了非常便利的FragmentPageAdapter,而這個adapter實現起來非常簡單:
public class TechFragmentPageAdapter extends FragmentPagerAdapter {private List<Fragment> fragmentList;public TechFragmentPageAdapter(FragmentManager fm, List<Fragment> fragmentList) {super(fm);this.fragmentList = fragmentList;}public Fragment getItem(int position) {return fragmentList.get(position);}public int getCount() {return fragmentList.size();} } 復制代碼現在我們一般的Activity都是繼承于AppCompatActivity,而這個activity可以
getSupportFragmentManager(); 復制代碼那么在實現以上的adapter時我們只要傳入我們的fragmentList就可以了。這樣的adapter既看起來舒服,又好使。但是ViewPager默認會加載下一頁,當你調用setOffscreenPageLimit(),并且將值設置為0,抱歉,沒啥用,因為當你設置的值小于1的時候默認還是1。那么,這個時候就需要我們自己去實現懶加載了。
實現
實現懶加載的關鍵是在于以下兩個方法:
/*** 文檔對于這個方法的描述是:Set a hint to the system about whether this * fragment's UI is currently visible to the user.**/ getUserVisibleHint() setUserVisibleHint(boolean isVisibleToUser) 復制代碼接下來讓我通過一段Log來了解這段故事,因為代碼結構比較簡單,只放其中的一段代碼上來,其他的,靠我們腦補就行了。
public class FirstFragment extends Fragment {private static final String TAG = "FirstFragment";public void onAttach(Context context) {Log.e(TAG, "onAttach");super.onAttach(context);}public void onCreate(@Nullable Bundle savedInstanceState) {Log.e(TAG, "onCreate");super.onCreate(savedInstanceState);}public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {Log.e(TAG, "onCreateView");return super.onCreateView(inflater, container, savedInstanceState);}public void onActivityCreated(@Nullable Bundle savedInstanceState) {Log.e(TAG, "onActivityCreated");super.onActivityCreated(savedInstanceState);}public void onStart() {Log.e(TAG, "onStart");super.onStart();}public void onResume() {Log.e(TAG, "onResume");super.onResume();}public void onPause() {Log.e(TAG, "onPause");super.onPause();}public void onStop() {Log.e(TAG, "onStop");super.onStop();}public void onDestroyView() {Log.e(TAG, "onDestroyView");super.onDestroyView();}public void onDestroy() {Log.e(TAG, "onDestroy");super.onDestroy();}public void onDetach() {Log.e(TAG, "onDetach");super.onDetach();}public boolean getUserVisibleHint() {Log.e(TAG, "getUserVisibleHint");return super.getUserVisibleHint();}public void setUserVisibleHint(boolean isVisibleToUser) {super.setUserVisibleHint(isVisibleToUser);Log.e(TAG, "setUserVisibleHint:" + isVisibleToUser);} }復制代碼非常簡單的一個Fragment,我只是在其中的各個方法中加入了Log這個操作而已,為了方便查看我使用了e這個級別的日志。類似的Fragment還有SecondFragment和ThirdFragment。當我使用FragmentPagerAdapter和ViewPager的時候,他們的Log輸出如下:
首先和我們預料的一樣,ViewPager的確有加載下一頁的特性,然后我們滑動到第二頁查看Log。
我們可以發現,當我們滑動到第二頁時,第三頁開始預加載,而且第二頁的setUserVisibleHint中的值已經被置為了true。也就是說當前頁面可見時,我們調用getUserVisibleHint()的值是true。那么我們可以根據這個特性去實現懶加載:** 當前頁面不可見,但是ViewPager預加載的時候,我們判斷當前頁面是否可見,不可見則不進行加載數據的操作,僅僅做布局初始化的工作。在當前頁面變為可用的時候,我們調用加載數據的方法,那么數據便在ViewPager滑動到當前頁面的時候開始加載了。**
以下是我封裝的代碼,我封裝無力,各位如果覺得可以便自取,如果覺得不行可以自己改進~
package com.lauren.simplenews.news.widget;import android.content.Context; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup;/*** Created by Luo_xiasuhuei321@163.com on 2016/8/29.** 實現懶加載的Fragment*/ public abstract class BaseLazyFragment extends Fragment {protected View mRootView;protected Context mContext;protected boolean isVisible;private boolean isPrepared;private boolean isFirst = true;//--------------------system method callback------------------------//public void onActivityCreated(@Nullable Bundle savedInstanceState) {super.onActivityCreated(savedInstanceState);isPrepared = true;initPrepare();}public void setUserVisibleHint(boolean isVisibleToUser) {super.setUserVisibleHint(isVisibleToUser);if(getUserVisibleHint()){isVisible = true;lazyLoad();}else{isVisible = false;onInvisible();}}public void onResume() {super.onResume();if(getUserVisibleHint()){setUserVisibleHint(true);}}public void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);mContext = getActivity();}public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {if(mRootView == null){mRootView = initView(inflater,container,savedInstanceState);}return mRootView;}//--------------------------------method---------------------------///*** 懶加載*/protected void lazyLoad(){if(!isPrepared || !isVisible || !isFirst){return;}initData();isFirst = false;}//--------------------------abstract method------------------------///*** 在onActivityCreated中調用的方法,可以用來進行初始化操作。*/protected abstract void initPrepare();/*** fragment被設置為不可見時調用*/protected abstract void onInvisible();/*** 這里獲取數據,刷新界面*/protected abstract void initData();/*** 初始化布局,請不要把耗時操作放在這個方法里,這個方法用來提供一個* 基本的布局而非一個完整的布局,以免ViewPager預加載消耗大量的資源。*/protected abstract View initView(LayoutInflater inflater,@Nullable ViewGroup container,@Nullable Bundle savedInstanceState); } 復制代碼###后話### 最近我搭建了自己的個人博客,雖然今天(9.2)沒時間完善了,但是以后有空我會完善一下的。而且有些文章我也不會再簡書更新……比如我想把我的java回爐重造一下……但是有關java的這些東西不怎么想放到簡書上,還是放到我自己的小窩里~
最后附上鏈接吧:https://xiasuhuei321.github.io 恩,域名暫時沒買,先就這么用著吧。
總結
以上是生活随笔為你收集整理的Fragment结合ViewPager之懒加载的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: html火影忍者网页设计作品,纯css3
- 下一篇: html循环自动点击事件,js循环遍历u