ViewPager實現Fragment懶加載

Fragment生命週期

Fragment的生命週期可以參考文章:

http://blog.csdn.net/lmj623565791/article/details/37970961

ViewPager實現首頁

首頁使用的是ViewPager和Fragment來實現,首頁效果圖:
首頁
但是Fragment的複雜的生命週期就會帶來一個問題,比如我們剛打開APP,這個時候我們只想AFragment加載數據,而其他的頁面的數據並不加載.但是真實的情況是,當AFragment可見,BFragment的數據也會同時加載.這是因爲使用ViewPager是會預加載Fragment的臨近的Fragment,雖然臨近的Fragment是不可見的但是他的OnResume方法其實已經執行了,如果我們的網絡初始化函數 寫在onCreateView裏面,顯然是不合適.下面我們來看一具體的日誌信息.
1.剛進入APP:
這裏寫圖片描述
這個時候,A和B的頁面邏輯同時加載完畢,如果在onCreateView裏面有網絡請求的邏輯,顯然這樣的效果不是,我們需要的.
2.單擊BFragment:
這裏寫圖片描述
在BFragment可見是,由於之前BFragment的onResume已經執行完畢,所以BFragment不會繼續執行他的生命週期,這樣時候會預加載CFragment.
4.單擊CFragment:
這裏寫圖片描述
這個時候,在預加載DFragment的時候,也會同時執行AFragment的onDestoryView方法即將Fragment的View被移除.
5.單擊DFragment:
這裏寫圖片描述
由於D Fragment的onResume方法已經執行完畢,所以BFragment的onDestoryView會執行.
6:在次回去單擊CFragment:
這裏寫圖片描述
7:再次回去單擊AFragment:
這裏寫圖片描述

setUserVisibleHint和getUserVisibleHint方法

getUserVisibleHint該方法用於告訴系統,這個Fragment的UI是否是可見.setUserVisibleHint方法是系統的方法,setUserVisibleHint方法是優先於onAttach方法執行的.在該方法內我們可以通過getUserVisibleHint方法獲取到當前的Fragment是否可見.如果可見設置isVisible爲true.如果不可見設置爲false.
代碼:
BaseFragment:

public abstract class BaseFragment extends Fragment
{

    //當前的Fragment是否可見
    protected boolean isVisible ;

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        Log.i("TAG",this.toString() +"  setUserVisibleHint");
        if(getUserVisibleHint())
        {
            isVisible = true;
            onVisible();
        }
        else
        {
            isVisible = false;
            onInVisible();
        }
    }

    /**
     * 當Fragment可見時執行的函數
     */
    private void onVisible()
    {
        lazyLoad();
    }

    /**
     * 當Fragment不可見執行的函數
     */
    private void onInVisible()
    {

    }
    protected abstract void lazyLoad();
}



MainActivity:

public class MainActivity extends FragmentActivity implements View.OnClickListener{
private List list = new ArrayList<>();
private AFragment aFragment;
private BFragment bFragment;
private CFragment cFragment;
private DFragment dFragment;

private ViewPager mvp;
private LinearLayout merchant_lay;
private LinearLayout order_lay;
private LinearLayout privilege_lay;
private LinearLayout mine_lay;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    initFragment();
    initView();
    MyAdapter adapter = new MyAdapter(this.getSupportFragmentManager(),list);
    mvp.setAdapter(adapter);
    mvp.setCurrentItem(0);
}

private void initFragment()
{
    aFragment = new AFragment();
    bFragment = new BFragment();
    cFragment = new CFragment();
    dFragment = new DFragment();
    list.add(aFragment);
    list.add(bFragment);
    list.add(cFragment);
    list.add(dFragment);
}

private void initView()
{
    mvp = (ViewPager)this.findViewById(R.id.mvp);
    merchant_lay = (LinearLayout)this.findViewById(R.id.merchant_lay);
    order_lay = (LinearLayout)this.findViewById(R.id.order_lay);
    privilege_lay = (LinearLayout)this.findViewById(R.id.privilege_lay);
    mine_lay = (LinearLayout)this.findViewById(R.id.mine_lay);


    merchant_lay.setOnClickListener(this);
    order_lay.setOnClickListener(this);
    privilege_lay.setOnClickListener(this);
    mine_lay.setOnClickListener(this);
}

@Override
public void onClick(View v) {
    switch (v.getId())
    {
        case R.id.merchant_lay:
            mvp.setCurrentItem(0);
            break;
        case R.id.order_lay:
            mvp.setCurrentItem(1);
            break;
        case R.id.privilege_lay:
            mvp.setCurrentItem(2);
            break;
        case R.id.mine_lay:
            mvp.setCurrentItem(3);
            break;
    }
}

}


Adapter:

public class MyAdapter extends FragmentPagerAdapter {
    private List<Fragment> mList;
    public MyAdapter(FragmentManager fm,List<Fragment> list) {
        super(fm);
        this.mList = list;
    }

    @Override
    public int getCount() {
        return mList != null ? mList.size() : 0;
    }

    @Override
    public Fragment getItem(int position) {
        return mList != null ? mList.get(position) : null;
    }
}


AFragmnet:

public class AFragment extends BaseFragment {
private static final String TAG = AFragment.class.getSimpleName();
//標誌是否已經加載完畢
private boolean isPrepared;
//是否已經加載過一次,第二次則不加載。
private boolean mHasLoadedOnce = false;
@Override
public void onAttach(Context context) {
Log.i(“TAG”, TAG + ” onAttach”);
super.onAttach(context);
}

@Override
public void onCreate(Bundle savedInstanceState) {
    Log.i("TAG", TAG + "  onCreate");
    super.onCreate(savedInstanceState);
}

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    Log.i("TAG", TAG + "  onCreateView");
    View view = inflater.inflate(R.layout.fragment_a,container,false);
    isPrepared = true;
    lazyLoad();
    return view;
}

@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
    Log.i("TAG", TAG + "  onActivityCreated");
    super.onActivityCreated(savedInstanceState);
}

@Override
public void onStart() {
    Log.i("TAG", TAG + "  onStart");
    super.onStart();
}

@Override
public void onResume() {
    Log.i("TAG", TAG + "  onResume");
    super.onResume();
}


@Override
public void onStop() {
    Log.i("TAG", TAG + "  onStop");
    super.onStop();
}

@Override
public void onPause() {
    Log.i("TAG", TAG + "  onPause");
    super.onPause();
}

@Override
public void onDestroyView() {
    Log.i("TAG", TAG + "  onDestroyView");
    super.onDestroyView();
}

@Override
public void onDestroy() {
    Log.i("TAG", TAG + "  onDestroy");
    super.onDestroy();
}


@Override
public void onDetach() {
    Log.i("TAG", TAG + "  onDetach");
    super.onDetach();
}

@Override
protected void lazyLoad()
{
    Log.i("TAG", TAG +"   lazy" + isPrepared + "   " + isVisible + "  " + mHasLoadedOnce);
    if (!isPrepared || !isVisible || mHasLoadedOnce) {
        return;
    }
    mHasLoadedOnce = true;
}

}

ViewPager的不可滑動設置

public class MyViewPager extends ViewPager {

    private boolean isCanScroll = false;

    public MyViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
    }

    public void setScanScroll(boolean isCanScroll) {
        this.isCanScroll = isCanScroll;
    }

    @Override
    public void scrollTo(int x, int y) {
        super.scrollTo(x, y);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent arg0) {
        if (isCanScroll) {
            return super.onInterceptTouchEvent(arg0);
        } else {
            return false;
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent arg0) {
        if (isCanScroll) {
            return super.onTouchEvent(arg0);
        } else {
            return false;
        }
    }

}

佈局文件:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <RelativeLayout
        android:id="@+id/main_activity_layout"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_weight="1"
        android:background="#CE112D"
        android:gravity="center_vertical"
        android:orientation="vertical" >


        <com.example.dengquan.lazyloadmodule.viewpager.MyViewPager
            android:id="@+id/mvp"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:background="@android:color/white"
            android:layout_above="@+id/bottomView">
        </com.example.dengquan.lazyloadmodule.viewpager.MyViewPager>

        <include
            android:id="@id/bottomView"
            layout="@layout/bottom_view"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:layout_alignParentBottom="true"/>
    </RelativeLayout>
</LinearLayout>

補充

如果想更新某個Fragment可以通過廣播來更新,或者(EventBus,otto).

參考文獻:

http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2014/1021/1813.html

代碼下載地址:

https://github.com/jessandroid/lazyloadfragment

發佈了38 篇原創文章 · 獲贊 10 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章