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

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

本文的主題是 ViewPager+Fragment+FragmentTabHost 實(shí)現(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>

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

5、關(guān)聯(lián)ViewPager與底部菜單
  • ViewPager實(shí)現(xiàn)OnPageChangeListener監(jiān)聽器,目的是讓ViewPager滑動的時(shí)候能夠帶著底部菜單聯(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實(shí)現(xiàn)setOnTabChangedListener,目的是當(dāng)點(diǎn)擊了下面的菜單時(shí),上面的ViewPager應(yīng)該滑動到對應(yīng)的Fragment
mTabHost.setOnTabChangedListener(new OnTabChangeListener()
        {

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

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容