Android開發(fā)之ViewPager+Fragment+FragmentTabHost實現(xiàn)底部菜單

在Android開發(fā)中,底部菜單是經(jīng)常要使用的厂置,如微信菩掏、微博、支付寶等昵济,實現(xiàn)底部菜單有好幾種方式智绸,大致分為:
  • 通過TabWidget實現(xiàn)
  • 隱藏TabWidget野揪,通過RadioGroup和RadioButton實現(xiàn)底部菜單欄
  • 通過FragmentTabHost實現(xiàn)
  • 通過5.0以后的TabLayout實現(xiàn)
  • 通過最近推出的 Bottom navigation

本文的主題是 ViewPager+Fragment+FragmentTabHost 實現(xiàn)底部菜單
1、構(gòu)造4個Fragment瞧栗,每個布局類似如下
<?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"
    android:orientation="vertical" 
    android:gravity="center">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="fragment1" 
        android:textSize="20dp"/>

</LinearLayout>
2斯稳、Activity布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

     <android.support.v4.view.ViewPager
        android:id="@+id/pager"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />

    <android.support.v4.app.FragmentTabHost
        android:id="@android:id/tabhost"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="@android:color/black" >
    </android.support.v4.app.FragmentTabHost>

</LinearLayout>

上面是一個ViewPager,用于裝載Fragment進(jìn)行滑動迹恐;下面放一個FragmentTabHost挣惰,用于存放底部菜單的具體內(nèi)容,它的顏色就是黑色的殴边,菜單的文字為白色憎茂,這樣好區(qū)分。

3找都、底部菜單布局唇辨,一般都是圖片在上廊酣,文字在下能耻,美工一般都會把圖片提前準(zhǔn)備好
<?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"
    android:gravity="center"
    android:orientation="vertical" >

    <ImageView
        android:id="@+id/tab_imageview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/tab_textview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="@android:color/white" />

</LinearLayout>
4、Activity代碼
//注意是繼承 FragmentActivity
public class MainActivity extends FragmentActivity
{

    // FragmentTabHost
    private FragmentTabHost mTabHost;
    // layoutInflater
    private LayoutInflater layoutInflater;
    // imageViewArray數(shù)組亡驰,用于顯示底部菜單
    private int imageViewArray[] = { R.drawable.mywork, R.drawable.mypatient,
            R.drawable.infusion, R.drawable.personal };
    // textViewArray數(shù)組
    private String textViewArray[] = { "工作", "回家", "互動", "我的" };
    // Fragment數(shù)組
    private List<Fragment> list = new ArrayList<Fragment>();
    // ViewPager
    private ViewPager vp;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_tab_layout);

        initView();
    }

    /**
     * 控件初始化
     */
    private void initView()
    {
        vp = (ViewPager) findViewById(R.id.pager);

        layoutInflater = LayoutInflater.from(this);
        mTabHost = (FragmentTabHost) findViewById(android.R.id.tabhost);
        mTabHost.setup(this, getSupportFragmentManager(), R.id.pager);

        Fragment1 fragment1 = new Fragment1();
        Fragment2 fragment2 = new Fragment2();
        Fragment3 fragment3 = new Fragment3();
        Fragment4 fragment4 = new Fragment4();
        list.add(fragment1);
        list.add(fragment2);
        list.add(fragment3);
        list.add(fragment4);

        int count = textViewArray.length;

        // 添加菜單內(nèi)容
        for (int i = 0; i < count; i++)
        {
            // 一個菜單就是一個TabSpec晓猛,然后添加到FragmentTabHost中
            TabSpec tabSpec = mTabHost.newTabSpec(textViewArray[i])
                    .setIndicator(getTabItemView(i));
            mTabHost.addTab(tabSpec, list.get(i).getClass(), null);
            // 默認(rèn)讓第一個選中
            mTabHost.getTabWidget().getChildAt(0)
                    .setBackgroundResource(R.drawable.selector_tab_background);
        }

        // ViewPager添加Adapter,這里用FragmentPagerAdapter
        vp.setAdapter(new FragmentPagerAdapter(getSupportFragmentManager())
        {

            @Override
            public int getCount()
            {

                return list.size();
            }

            @Override
            public android.support.v4.app.Fragment getItem(int arg0)
            {
                return list.get(arg0);
            }
        });

    }

    private View getTabItemView(int i)
    {
        View view = layoutInflater.inflate(R.layout.tab_content, null);
        ImageView mImageView = (ImageView) view
                .findViewById(R.id.tab_imageview);
        TextView mTextView = (TextView) view.findViewById(R.id.tab_textview);
        mImageView.setBackgroundResource(imageViewArray[i]);
        mTextView.setText(textViewArray[i]);
        return view;
    }

}

上面的 selector_tab_background.xml文件如下凡辱,只是改變了一下背景色來示意選中

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:state_selected="true" android:drawable="@color/purple"/>
    <item android:state_focused="true" android:drawable="@color/purple"/>
    <item android:state_pressed="true" android:drawable="@color/purple"/>
    <item android:drawable="@android:color/black"/>

</selector>

這樣寫了以后戒职,只能實現(xiàn)底部有菜單,上面能滑動透乾,但是底部菜單和上面的ViewPager并沒有關(guān)聯(lián)起來洪燥,怎么關(guān)聯(lián)呢?首先乳乌,上面滑動的時候捧韵,需要監(jiān)聽滑動到哪里了,然后下面的菜單跟著聯(lián)動汉操;同理再来,如果點擊了下面的菜單,上面的ViewPager應(yīng)該滑動到對應(yīng)的Fragment

5磷瘤、關(guān)聯(lián)ViewPager與底部菜單
  • ViewPager實現(xiàn)OnPageChangeListener監(jiān)聽器芒篷,目的是讓ViewPager滑動的時候能夠帶著底部菜單聯(lián)動
    vp.setOnPageChangeListener(new OnPageChangeListener()
        {

            @Override
            public void onPageScrollStateChanged(int arg0)
            {

            }

            @Override
            public void onPageScrolled(int arg0, float arg1, int arg2)
            {

            }

            @Override
            public void onPageSelected(int arg0)
            {
                // 選中菜單
                mTabHost.setCurrentTab(arg0);
                // 設(shè)置對應(yīng)菜單高亮
                mTabHost.getTabWidget()
                        .getChildAt(arg0)
                        .setBackgroundResource(
                                R.drawable.selector_tab_background);
            }
        });
  • FragmentTabHost實現(xiàn)setOnTabChangedListener,目的是當(dāng)點擊了下面的菜單時采缚,上面的ViewPager應(yīng)該滑動到對應(yīng)的Fragment
mTabHost.setOnTabChangedListener(new OnTabChangeListener()
        {

            @Override
            public void onTabChanged(String tabId)
            {
                // 獲取點擊的菜單的位置
                int position = mTabHost.getCurrentTab();
                // ViewPager滑動到對應(yīng)的位置
                vp.setCurrentItem(position);
            }
        });

至此针炉,這個雙向關(guān)聯(lián)的底部菜單就已經(jīng)完成了。如果要求內(nèi)容不需要滑動扳抽,如微信糊识、支付寶那種绩社,只有底部點擊切換Fragment的功能,那么只需要將Activity布局中的ViewPager換成一個FrameLayout占位赂苗,然后在程序替換Fragment即可~~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末愉耙,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子拌滋,更是在濱河造成了極大的恐慌朴沿,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,718評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件败砂,死亡現(xiàn)場離奇詭異赌渣,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)昌犹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評論 3 385
  • 文/潘曉璐 我一進(jìn)店門坚芜,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人斜姥,你說我怎么就攤上這事鸿竖。” “怎么了铸敏?”我有些...
    開封第一講書人閱讀 158,207評論 0 348
  • 文/不壞的土叔 我叫張陵缚忧,是天一觀的道長。 經(jīng)常有香客問我杈笔,道長闪水,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,755評論 1 284
  • 正文 為了忘掉前任蒙具,我火速辦了婚禮球榆,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘禁筏。我一直安慰自己持钉,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,862評論 6 386
  • 文/花漫 我一把揭開白布融师。 她就那樣靜靜地躺著右钾,像睡著了一般。 火紅的嫁衣襯著肌膚如雪旱爆。 梳的紋絲不亂的頭發(fā)上舀射,一...
    開封第一講書人閱讀 50,050評論 1 291
  • 那天,我揣著相機(jī)與錄音怀伦,去河邊找鬼脆烟。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的羊苟。 我是一名探鬼主播页响,決...
    沈念sama閱讀 39,136評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼肋层,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了渔伯?” 一聲冷哼從身側(cè)響起爆价,我...
    開封第一講書人閱讀 37,882評論 0 268
  • 序言:老撾萬榮一對情侶失蹤担汤,失蹤者是張志新(化名)和其女友劉穎敏簿,沒想到半個月后明也,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,330評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡惯裕,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,651評論 2 327
  • 正文 我和宋清朗相戀三年温数,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蜻势。...
    茶點故事閱讀 38,789評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡撑刺,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出握玛,到底是詐尸還是另有隱情够傍,我是刑警寧澤,帶...
    沈念sama閱讀 34,477評論 4 333
  • 正文 年R本政府宣布败许,位于F島的核電站王带,受9級特大地震影響淑蔚,放射性物質(zhì)發(fā)生泄漏市殷。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,135評論 3 317
  • 文/蒙蒙 一刹衫、第九天 我趴在偏房一處隱蔽的房頂上張望醋寝。 院中可真熱鬧,春花似錦带迟、人聲如沸音羞。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,864評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽嗅绰。三九已至,卻和暖如春搀继,著一層夾襖步出監(jiān)牢的瞬間窘面,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,099評論 1 267
  • 我被黑心中介騙來泰國打工叽躯, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留财边,地道東北人。 一個月前我還...
    沈念sama閱讀 46,598評論 2 362
  • 正文 我出身青樓点骑,卻偏偏與公主長得像酣难,于是被迫代替她去往敵國和親谍夭。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,697評論 2 351

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