1. 程式人生 > >Fragment基本介紹(三) ----之Tablayout+ViewPage+Fragment

Fragment基本介紹(三) ----之Tablayout+ViewPage+Fragment

一,兩種adapter使用場景 

- FragmentStatePagerAdapter和FragmentPagerAdapter

 

- 1,兩種Adapter特點分析

 

    a)fragmentPagerAdapter帶有快取,記憶體開銷大,響應速度很快

 

    b)FragmentStatePagerAdapter沒有快取,記憶體開銷小,響應速度稍慢。

 

    c)FragmentStatePagerAdapter

如果想用快取,需要自己動手寫。

    

- 2,使用場景分析

 

    a)FragmentPagerAdapter快取所有頁面,因此適合fragment頁面較少(20以內),並且單個頁面開銷小(沒有webview、surfaceView重量元件,或大量圖片)

 

    d)FragmentStatePagerAdapter相反,適合記憶體壓力很大的場景。可以自己控制快取邏輯。

    e)實戰時根據需求(使用者行為)選擇。比如證券APP不需要做快取,而谷歌市場快取時間應該在1天以內。

 

 

二,ViewPager的setOffscreenPageLimit()

     viewPager.setOffscreenPageLimit(1);

 

- 1,setOffscreenPageLimit 預設值是1,

    預設載入3個頁面.當前頁面和左右各一個頁面

    但如果載入的是第1頁,就只會預載入第2頁,總共是2頁

    如果滑動到第2頁,就會預載入第1頁和第3頁,總共是3頁

    二層意思

    一是 ViewPager 會預載入幾頁; 

    二是 ViewPager 會快取 2*n+1 頁(n為設定的值).

 

- 2.ViewPager 中的 fragment 是否執行 onViewDestory 或者 onDestory 與 setOffscreenPageLimit 方法設定的值有關. 

 

- 3,懶載入:setOffscreenPageLimit(0)

    - 但是,修改後就會有一個麻煩的地方,因為移動時不會預先載入下一個介面的關係,所以會看到一片黑色的背景.  

    如果當前載入的頁面有多個請求, 又預載入下個頁面的請求, 導致多個任務等待, 這會影響到當前頁面的請求速度. 所以合理的做法是當頁面對於使用者可見時再去請求資料.

 

- 4,不做懶載入(預載入)

    如果當前頁面和隔壁頁面網路請求單一,就可以使用預載入,這樣使用者體驗很好

 

 

 

三,程式碼實現

(一)效果圖

 

(二),佈局展示

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="match_parent"

android:layout_height="match_parent"

xmlns:app="http://schemas.android.com/apk/res-auto"

android:fitsSystemWindows="true"

android:orientation="vertical">


<android.support.design.widget.TabLayout

android:id="@+id/home_tab"

app:tabIndicatorHeight="0dp"

app:tabMode="scrollable"

app:tabBackground="@color/freecolor_white"

android:layout_width="match_parent"

android:layout_height="wrap_content">

</android.support.design.widget.TabLayout>



<android.support.v4.view.ViewPager

android:id="@+id/home_page"

android:layout_width="match_parent"

android:layout_height="0dp"

android:layout_weight="1"

/>


</LinearLayout>

 

(三)父Fragment中的程式碼

1,Fragment巢狀,要使用getChildFragmentManager.

2,背景圖片需要用到自定義tab.setCustomView

package laobi.com.home;

import android.support.design.widget.TabLayout;
import android.support.v4.view.ViewPager;
import android.view.View;
import android.widget.TextView;

import laobi.com.core.BaseFragment;
import laobi.com.home.adapter.MainFragmentPagerAdapter;


/**
 * Created by biyaobing on 2018/3/1.
 */

public class HomeFragment extends BaseFragment {

    private TabLayout mHome_tab;
    private ViewPager mHome_page;
    private String [] titles = {"標題一","標題二","標題三","標題四","標題五","標題六"};
    private View mView;


    @Override
    protected View initView() {
        mView = View.inflate(mContext, R.layout.fragment_home, null);
        return mView;
    }

    @Override
    protected void init() {
        intiUI(mView);
    }


    private void intiUI(View view) {
        mHome_tab = (TabLayout) view.findViewById(R.id.home_tab);
        mHome_page = (ViewPager) view.findViewById(R.id.home_page);
        mHome_page.setAdapter(new MainFragmentPagerAdapter(getChildFragmentManager(),titles));//getSupportFragmentManager
        mHome_page.setOffscreenPageLimit(2);//設定預載入的頁面數量,設定0無效,因為原始碼最低值是1
        //方法的呼叫必須在viewpager設定完介面卡後呼叫,如果在設定介面卡之前呼叫會拋異常
        mHome_tab.setupWithViewPager(mHome_page);
        setCustomeTab();
        initPageListener();
    }

    private void setCustomeTab() {
        for (int i = 0; i < titles.length; i++) {
            TabLayout.Tab tab = mHome_tab.getTabAt(i);//獲得每一個tab
            tab.setCustomView(R.layout.my_tablayout);//給每一個tab設定view
            TextView mTv_custome = (TextView) tab.getCustomView().findViewById(R.id.tv_title);
            mTv_custome.setText(titles[i]);//設定tab上的文字
            if (i == 0) {
                setChecked(mTv_custome);
            }
        }
    }

    private void setChecked(TextView mTv_custome) {
        mTv_custome.setSelected(true);
        mTv_custome.setBackgroundResource(R.drawable.bg);
        mTv_custome.setTextColor(getResources().getColor(R.color.freecolor_white));
    }


    private void initPageListener() {
        mHome_tab.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                TextView textView = (TextView) tab.getCustomView().findViewById(R.id.tv_title);
                setChecked(textView);
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {
                TextView textView = (TextView) tab.getCustomView().findViewById(R.id.tv_title);
                textView.setBackgroundColor(getResources().getColor(R.color.freecolor_white));
                textView.setTextColor(getResources().getColor(R.color.tv_black));
            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {

            }
        });
    }
}

 

(四)FragmentPagerAdapter種的程式碼

public class MainFragmentPagerAdapter extends FragmentPagerAdapter {

    private final String[] mTitles;

    /**
     * 告訴adapter每個頁面的標題
     * @param position
     * @return
     */
    @Override
    public CharSequence getPageTitle(int position) {
        return mTitles[position];
    }

    public MainFragmentPagerAdapter(FragmentManager fm, String[] titles) {
        super(fm);
        this.mTitles = titles;
    }

    @Override
    public Fragment getItem(int position) {
        Fragment fragment;
        switch (position){
            case 0:
                Bundle bundle = new Bundle();
                bundle.putString("test","測試首頁11成功");
                fragment = Fragment1_Home.newInstance(bundle);
                break;
            case 1:
                Bundle bundle2 = new Bundle();
                bundle2.putString("test","測試2222成功");
                fragment = Fragment2_Home.newInstance(bundle2);
                break;
            case 2:
                Bundle bundle3= new Bundle();
                bundle3.putString("test","測試333成功");
                fragment = Fragment3_Home.newInstance(bundle3);
                break;
            case 3:
                Bundle bundle4= new Bundle();
                bundle4.putString("test","測試444成功");
                fragment = Fragment3_Home.newInstance(bundle4);
                break;
            case 4:
                Bundle bundle5= new Bundle();
                bundle5.putString("test","測試555成功");
                fragment = Fragment3_Home.newInstance(bundle5);
                break;
            case 5:
                Bundle bundle6= new Bundle();
                bundle6.putString("test","測試666成功");
                fragment = Fragment3_Home.newInstance(bundle6);
                break;
            default:
                Bundle bundle1 = new Bundle();
                bundle1.putString("test","測試首頁11成功");
                fragment = Fragment1_Home.newInstance(bundle1);
        }
        return fragment;
    }

    @Override
    public int getCount() {
        return mTitles.length;
    }
}