Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> viewpager+fragment的懶加載

viewpager+fragment的懶加載

編輯:關於Android編程

正文

進入正題,主要講解viewpager+fragment實現微信滑動切換頁面的功能,並且附帶切換效果,功能其實並不難,只是需要把知識點關聯起來

應為使用模擬器原因,出現模糊背景,手機上面是沒有的

1.分析用到的知識點

(1). fragment的懶加載
(2). viewpager的滑動監聽事件
(3). 控件alpha的設置、fragment切換的效果

2.功能實現

2.1.fragment的懶加載

這裡寫圖片描述

這裡寫圖片描述

當viewpager加載第一個fragment的時候會預加載第二個fragment,當加載第二個fragment的時候,會預加載第三個fragment,同時會進行數據加載,這種做法肯定不好,當第幾個fragment顯示的時候才應該加載數據,這裡就用到了懶加載:

public abstract class LazyFragment extends Fragment{
    //用於標記視圖是否初始化
    protected boolean isVisible;
    //在onCreate方法之前調用,用來判斷Fragment的UI是否是可見的
    @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(){}
}

自定義LazyFragment類只需要繼承Fragment,實現setUserVisibleHint方法來判斷fragment視圖是否可見,定義三個方法,當視圖可見的時候,isVisible = true,調用lazyLoad方法,其它fragment只需要繼承該fragment即可:

public class OneFragment extends LazyFragment {
    // 標志fragment是否初始化完成
    private boolean isPrepared;
    private View view;
    @Override
    public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState) {
        if(view == null){
            view = inflater.inflate(R.layout.fragment_one , container , false);
            ButterKnife.inject(this, view);
            KLog.e("TAG" , "oneFragment--onCreateView");
            isPrepared = true;
            lazyLoad();
        }
        return view;
    }


    @Override
    protected void lazyLoad() {
        if(!isPrepared || !isVisible) {
            return;
        }
        KLog.e("TAG" , "oneFragment--lazyLoad");
    }
}

由於setUserVisibleHint方法在onCreateView方法之前調用,所以定義字段isPrepared 來判斷fragment是否初始化完成,防止報nullpointerexception,只有當視圖可見並且fragment初始化完成執行lazyLoad方法,可以理解成就是onStart方法,再進行數據加載,這也就是懶加載。

注:
a.由於每次加載fragment都會重新執行onCreateView方法,所以我用view來判斷fragment是否初始化過,初始化過就不在初始化,當然要是想每次都初始化就不必判斷
b.每次fragment視圖可見的時候lazyLoad方法都會被調用,若是只想加載一次可自定義字段判斷是否加載過數據

這裡寫圖片描述

這裡寫圖片描述

2.2.viewpager的滑動監聽事件

首先設置viewpager的適配器,FragmentPagerAdapter的子類只要實現 getItem(int) 和 getCount()方法:

public class FragmentAdapter extends FragmentPagerAdapter{
    //fragment 集合
    private List mFragmentList = new ArrayList<>();

    public FragmentAdapter(FragmentManager fm , List list) {
        super(fm);
        this.mFragmentList = list;
    }

    @Override
    public Fragment getItem(int position) {
        return mFragmentList.get(position);
    }

    @Override
    public int getCount() {
        return mFragmentList.size();
    }
}

其次設置viewpager監聽事件:

//viewpager滑動監聽
        mMainViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                changAlpha(position, positionOffset);
            }
            @Override
            public void onPageSelected(int position) {
                changAlpha(position);
            }
            @Override
            public void onPageScrollStateChanged(int state) {}
        });

onPageScrolled方法的表示viewpager正在滑動:

position當向右滑動的時候表示當前頁面的下標,向左滑動的時候表示左邊頁面的下標;
positionOffset是當前頁面滑動比例,如果頁面向右翻動,這個值不斷變大,最後在趨近1的情況後突變為0。如果頁面向左翻動,這個值不斷變小,最後變為0;
positionOffsetPixels是當前頁面滑動像素,變化情況和positionOffset一致。

參數的變化隨方向的相反正好相反,下面我們寫tab的顏色漸變就不需要判斷方向了

根據該方法的positionOffset和position這兩個參數就可以實現tab滑動顏色漸變的效果,先看一下布局:


        <framelayout android:id="@+id/m_main_fw_lay" android:layout_height="wrap_content" android:layout_weight="1" android:layout_width="0dp"></framelayout>

每個tab我是使用的2個button,一個默認顏色,一個選中顏色,我們只需要根據滑動比例來改變選中顏色button的alpha即可:

/**
     * 根據滑動設置透明度
     */
    private void changAlpha(int pos, float posOffset) {
        int nextIndex = pos + 1;
        if(posOffset > 0){
            //設置tab的顏色漸變效果
            mButtonList.get(nextIndex).setAlpha(posOffset);
            mButtonList.get(pos).setAlpha(1 - posOffset);
            //設置fragment的顏色漸變效果
            mFragmentList.get(nextIndex).getView().setAlpha(posOffset);
            mFragmentList.get(pos).getView().setAlpha(1 - posOffset);
            //設置fragment滑動視圖由大到小,由小到大的效果
            mFragmentList.get(nextIndex).getView().setScaleX(0.5F + posOffset/2);
            mFragmentList.get(nextIndex).getView().setScaleY(0.5F + posOffset/2);
            mFragmentList.get(pos).getView().setScaleX(1-(posOffset/2));
            mFragmentList.get(pos).getView().setScaleY(1-(posOffset/2));
        }
    }

當posOffset > 0 ,說明viewpager在滑動;前面說了onPageScrolled方法參數隨滑動方向的變化是相反的所以這裡只需要寫一個方法便可實現兩個方向滑動顏色漸變的效果,道理就是改變兩個button的Alpha值就可實現漸變效果,是不是挺簡單;
關於fragemnt的顏色漸變和伸縮效果,在上面也已經貼出了代碼,就不詳細解釋了,相信大家都能看懂;

onPageSelected方法表示滑動抬起手指那一刻所執行的方法,參數position代表的是當前頁面的下標,所以當滑動結束之後,我們把當前頁面的tab、fragment.getView()的Alpha設置為1.0f,其它tab設置為0.0f ; fragment的x、y軸設置為1.0f(需要判斷fragment.getView()是否為null,防止報nullpointerexception),其他的0.0f即可:

 /**
      * 一開始運行、滑動和點擊tab結束後設置tab的透明度,fragment的透明度和大小
      */
    private void changAlpha(int postion) {
        for (int i = 0; i < mButtonList.size(); i++) {
            if (i == postion) {
                mButtonList.get(i).setAlpha(1.0f);
                if(null != mFragmentList.get(i).getView()){
                    mFragmentList.get(i).getView().setAlpha(1.0f);
                    mFragmentList.get(i).getView().setScaleX(1.0f);
                    mFragmentList.get(i).getView().setScaleY(1.0f);
                }
            } else {
                mButtonList.get(i).setAlpha(0.0f);
                if(null != mFragmentList.get(i).getView()){
                    mFragmentList.get(i).getView().setAlpha(0.0f);
                    mFragmentList.get(i).getView().setScaleX(0.0f);
                    mFragmentList.get(i).getView().setScaleY(0.0f);
                }
            }
        }
    }

把所有fragemnt放入集合中遍歷判斷即可;

主要代碼就這些,有不解的地方請看Demo

源碼下載

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved