Fragment的應用之底部導航欄的實現(xiàn)(二)之應用ViewPager

效果圖

底部導航欄(二).gif

什么是ViewPager

該文要講到的實際是在Fragment的應用之底部導航欄的實現(xiàn)(一)的基礎上應用了ViewPager。使得底部導航欄的切換有了滑動的效果,同時支持了頁面的手勢滑動切換仑濒。

ViewPager

ViewPager在很多App中都會有應用位仁,那它到底干什么的?我以前也沒用過,不過專門學習了之后,覺得這個控件還是很好理解的,在我看來它其實和Listview這一類ViewGroup差不多乍构,只不過它是橫向滑動的,而且通常情況下每一個item的寬度是屏幕的寬度扛点,再通俗點說就是可以左右滑動切換顯示的View哥遮,且屏幕上同時只能看到一個item。具體能實現(xiàn)的效果就是上面效果圖所展示的那樣陵究。

ViewPager的使用

既然ViewPager類似于ListView眠饮,那他的使用就應該也類似于它。所以ViewPager也有一個適配器铜邮,而且ViewPager通常會和Fragment搭配使用仪召,官方也提供了FragmentPagerAdapter和FragmentStatePagerAdapter兩個適配器類供我們使用。關于ViewPager的使用可以有很多東西要寫松蒜,不過該文中只討論了它最基本的使用

布局

整體的布局基本上沿用上一篇文章demo的布局扔茅。不過在主界面布局上做了一定的修改。
之前是用一個FrameLayout來放置Fragment秸苗,而這里自然就要使用ViewPager來代替之前的FrameLayout召娜。注意ViewPager是在V4擴展包當中的

<android.support.v4.view.ViewPager
        android:id="@+id/my_viewpager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@+id/tab_linear">
</android.support.v4.view.ViewPager>

自定義Fragment

現(xiàn)在布局文件都準備好了,接下來就是定義要顯示的View也就是自定義的Fragment惊楼,為了更好的顯示滑動切換的效果玖瘸,給每一個Fragment設置了不同的背景色秸讹。

public class FragmentTest extends Fragment{

    private String fragmentText;
    private int backColor;

    private TextView fragmentTextView;

    public FragmentTest(String fragmentText,int color) {
        this.fragmentText=fragmentText;
        this.backColor=color;
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view=inflater.inflate(R.layout.test_fragment,container,false);
        RelativeLayout relativeLayout= (RelativeLayout) view.findViewById(R.id.fragment_relative_layout);
        fragmentTextView= (TextView) view.findViewById(R.id.fragment_text);
        relativeLayout.setBackgroundColor(backColor);
        fragmentTextView.setText(fragmentText);
        return view;
    }
}

自定義適配器

現(xiàn)在Fragment都已經(jīng)準備好了,就相當于ListView中自定義的布局item準備好了雅倒,所以接下來就是要自定義ViewPager的適配器璃诀。讓它繼承自FragmentPagerAdapter。

重寫函數(shù)

自定義該適配器需要至少重寫兩個函數(shù)

  • 一個是public Fragment getItem(int position)蔑匣,重寫這個函數(shù)就是要根據(jù)索引顯示對應的Fragment到屏幕上劣欢;
  • 一個是public int getCount(),這個函數(shù)很顯然是返回ViewPager中所有View即Fragment的總數(shù)的裁良。

構(gòu)造器

另外還需要實現(xiàn)一個帶FragmentManager的構(gòu)造器 氧秘,用于初始化所有的Fragment
下面是自定義MyViewPagerAdapter

public class MyViewPagerAdapter extends FragmentPagerAdapter{

    private final int PAFER_NUM=4;
    private FragmentTest fragmentTest1;
    private FragmentTest fragmentTest2;
    private FragmentTest fragmentTest3;
    private FragmentTest fragmentTest4;

    public MyViewPagerAdapter(FragmentManager fm) {
        super(fm);
        fragmentTest1=new FragmentTest("Home", Color.rgb(34,139,34));
        fragmentTest2=new FragmentTest("List",Color.rgb(255,99,71));
        fragmentTest3=new FragmentTest("Polymer",Color.rgb(0,139,139));
        fragmentTest4=new FragmentTest("User",Color.rgb(139,0,139));
    }

    @Override
    public Fragment getItem(int position) {
        Fragment fragment=null;
        switch (position){
            case MainActivity.PAGE_ONE:
                fragment=fragmentTest1;
                break;
            case MainActivity.PAGE_TWO:
                fragment=fragmentTest2;
                break;
            case MainActivity.PAGE_THREE:
                fragment=fragmentTest3;
                break;
            case MainActivity.PAGE_FOUR:
                fragment=fragmentTest4;
                break;
            default:
                break;
        }
        return fragment;
    }

    @Override
    public int getCount() {
        return PAFER_NUM;
    }
}

可以看出ViewPager的適配器和ListView這種的適配器不一樣,ListView的數(shù)據(jù)是從構(gòu)造器傳進來的趴久,而ViewPager的適配器的數(shù)據(jù)源就是Fragment,所以它是直接在自定義適配器定義并初始化了所有的Fragment搔确。

使用ViewPager

ViewPager的基本使用其實很簡單彼棍。

  • 首先用FindViewById初始化ViewPager的實例viewPager;
  • 調(diào)用自定義的MyViewPagerAdapter適配器得到一個適配器實例adapter膳算,然后調(diào)用viewPager的setAdapter傳入該adapter座硕,這樣ViewPager其實就已經(jīng)準備好了;
  • 接下來還要給ViewPager添加頁面滑動的事件監(jiān)聽涕蜂,重寫onPageScrollStateChanged方法以處理手勢滑動要處理的邏輯华匾;
  • 利用setCurrentItem方法給viewPager設置一個初始的Fragment;

具體的代碼:

public class MainActivity extends AppCompatActivity implements View.OnClickListener,ViewPager.OnPageChangeListener{

    LinearLayout homeLinear;

    LinearLayout listLinear;

    LinearLayout polyLinear;

    LinearLayout userLinear;

    private FragmentManager mfragmentManger;

    private ViewPager viewPager;

    private MyViewPagerAdapter myViewPagerAdapter;

    public static final int PAGE_ONE=0;
    public static final int PAGE_TWO=1;
    public static final int PAGE_THREE=2;
    public static final int PAGE_FOUR =3;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        homeLinear= (LinearLayout) findViewById(R.id.linear_home);
        listLinear= (LinearLayout) findViewById(R.id.linear_list);
        polyLinear= (LinearLayout) findViewById(R.id.linear_polymer);
        userLinear= (LinearLayout) findViewById(R.id.linear_user);
        viewPager= (ViewPager) findViewById(R.id.my_viewpager);
        homeLinear.setOnClickListener(this);
        listLinear.setOnClickListener(this);
        polyLinear.setOnClickListener(this);
        userLinear.setOnClickListener(this);
        viewPager.addOnPageChangeListener(this);
        myViewPagerAdapter=new MyViewPagerAdapter(getSupportFragmentManager());
        viewPager.setAdapter(myViewPagerAdapter);
        viewPager.setCurrentItem(PAGE_ONE);
        homeLinear.performClick();

    }

    @Override
    public void onClick(View view) {
        setAllFalse();
        switch (view.getId()){
            case R.id.linear_home:
                homeLinear.setSelected(true);
                viewPager.setCurrentItem(PAGE_ONE);
                break;
            case R.id.linear_list:
                listLinear.setSelected(true);
                viewPager.setCurrentItem(PAGE_TWO);
                break;
            case R.id.linear_polymer:
                polyLinear.setSelected(true);
                viewPager.setCurrentItem(PAGE_THREE);
                break;
            case R.id.linear_user:
                userLinear.setSelected(true);
                viewPager.setCurrentItem(PAGE_FOUR);
                break;
        }

    }


    private void setAllFalse() {
        homeLinear.setSelected(false);
        listLinear.setSelected(false);
        polyLinear.setSelected(false);
        userLinear.setSelected(false);
    }

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

    }

    @Override
    public void onPageSelected(int position) {

    }

    @Override
    public void onPageScrollStateChanged(int state) {
        if(state==2){
            setAllFalse();
            switch (viewPager.getCurrentItem()){
                case PAGE_ONE:
                    homeLinear.setSelected(true);
                    break;
                case PAGE_TWO:
                    listLinear.setSelected(true);
                    break;
                case PAGE_THREE:
                    polyLinear.setSelected(true);
                    break;
                case PAGE_FOUR:
                    userLinear.setSelected(true);
            }
        }

    }
}

總結(jié)

本文主要是應用了ViewPager實現(xiàn)底部菜單導航机隙,不過底部導航的方法和形式還有很多種蜘拉,后續(xù)還會記錄其他的一些常用的方式。

歡迎批評指正有鹿,小弟感激不盡旭旭。

2017.4.12 22:45
806 實驗室

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市葱跋,隨后出現(xiàn)的幾起案子持寄,更是在濱河造成了極大的恐慌,老刑警劉巖娱俺,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件稍味,死亡現(xiàn)場離奇詭異,居然都是意外死亡荠卷,警方通過查閱死者的電腦和手機模庐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來僵朗,“玉大人赖欣,你說我怎么就攤上這事屑彻。” “怎么了顶吮?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵社牲,是天一觀的道長。 經(jīng)常有香客問我悴了,道長搏恤,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任湃交,我火速辦了婚禮熟空,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘搞莺。我一直安慰自己息罗,他們只是感情好,可當我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布才沧。 她就那樣靜靜地躺著迈喉,像睡著了一般。 火紅的嫁衣襯著肌膚如雪温圆。 梳的紋絲不亂的頭發(fā)上挨摸,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天,我揣著相機與錄音岁歉,去河邊找鬼得运。 笑死,一個胖子當著我的面吹牛锅移,可吹牛的內(nèi)容都是我干的熔掺。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼帆啃,長吁一口氣:“原來是場噩夢啊……” “哼瞬女!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起努潘,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤诽偷,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后疯坤,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體报慕,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年压怠,在試婚紗的時候發(fā)現(xiàn)自己被綠了眠冈。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖蜗顽,靈堂內(nèi)的尸體忽然破棺而出布卡,到底是詐尸還是另有隱情,我是刑警寧澤雇盖,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布忿等,位于F島的核電站,受9級特大地震影響崔挖,放射性物質(zhì)發(fā)生泄漏贸街。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一狸相、第九天 我趴在偏房一處隱蔽的房頂上張望薛匪。 院中可真熱鬧,春花似錦脓鹃、人聲如沸逸尖。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽冷溶。三九已至,卻和暖如春尊浓,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背纯衍。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工栋齿, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人襟诸。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓瓦堵,卻偏偏與公主長得像,于是被迫代替她去往敵國和親歌亲。 傳聞我的和親對象是個殘疾皇子菇用,可洞房花燭夜當晚...
    茶點故事閱讀 44,577評論 2 353

推薦閱讀更多精彩內(nèi)容