Android底部菜单的两种实现方式

时间:2022-11-12 08:23:07

市面上的APP常见的一个UI界面就是底部有多个菜单按钮,通过点击不同的按钮切换不同的页面。如微信,QQ等..
之前在开发一个新闻客户端的时候也使用了这种布局,当时使用的是 RadioGroup +RadioButton 来完成的。
后面在开发一个即时通讯APP的时候发现使用RadioGroup +RadioButton有一些局限行,于是改成用 FragmentTabHost 来完成。
这里简单记录一下如何用这两种技术来实现底部菜单的效果:

RadioGroup+RadioButton


<?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.support.v4.view.ViewPager
android:id="@+id/myViewPager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
/>

<RadioGroup
android:id="@+id/rg_group"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@mipmap/bottom_tab_bg"
android:orientation="horizontal"
>

<RadioButton
android:id="@+id/rb_home"
style="@style/BottomTabStyle"
android:drawableTop="@drawable/btn_tab_home_selector"
android:text="首页" />


<RadioButton
android:id="@+id/rb_news"
style="@style/BottomTabStyle"
android:drawableTop="@drawable/btn_tab_news_selector"
android:text="新闻中心" />


<RadioButton
android:id="@+id/rb_smart"
style="@style/BottomTabStyle"
android:drawableTop="@drawable/btn_tab_smart_selector"
android:text="智慧服务" />


<RadioButton
android:id="@+id/rb_gov"
style="@style/BottomTabStyle"
android:drawableTop="@drawable/btn_tab_gov_selector"
android:text="政务" />


<RadioButton
android:id="@+id/rb_setting"
style="@style/BottomTabStyle"
android:drawableTop="@drawable/btn_tab_setting_selector"
android:text="设置" />

</RadioGroup>
</LinearLayout>

style与selector的内容此处不给出。

//获取资源
RadioGroup radioGroup = (RadioGroup) view.findViewById(R.id.rg_group);

ViewPager noScrollViewPager = = (NoScrollViewPager) view.findViewById(R.id.noScrollViewPager);
//给ViwPage设置Adapter
noScrollViewPager.setAdapter(XXXX);
radioGroup = (RadioGroup) view.findViewById(R.id.rg_group);
//默认radioGroup的那个是被选中的
radioGroup.check(R.id.rb_home);
//还需在viewpager中显示该radioGroup对应的viewpager
xxxxx
//设置RadioGroup的点击监听,用来设置点击切换界面
radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup radioGroup, int i) {
switch (i){
case R.id.rb_home:
//点击不同的radioGroup刷新到不同的viewpager
noScrollViewPager.setCurrentItem(0, false);
break;
case R.id.rb_news:
noScrollViewPager.setCurrentItem(1,false);
break;
case R.id.rb_smart:
noScrollViewPager.setCurrentItem(2,false);
break;
case R.id.rb_gov:
noScrollViewPager.setCurrentItem(3,false);
break;
case R.id.rb_setting:
noScrollViewPager.setCurrentItem(4,false);
break;

}
}
});

如上所示的代码即可完成。效果图:

Android底部菜单的两种实现方式
这样虽然可以完成底部菜单的显示,但这种方法有这强的局限性。比如在设置RadioButton的时候是使用drawableTop来加入图片的。这种做法不能设置图片的宽高等属性,在某些时候则这种方法不可用。

FragmentTabHost

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".HomeActivity">


<FrameLayout
android:id="@+id/main_frameLayout"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
/>

<!--如下的写法不能变,id值都是固定的-->
<android.support.v13.app.FragmentTabHost
android:id="@android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>

<FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="0">

</FrameLayout>
</android.support.v13.app.FragmentTabHost>
</LinearLayout>

Activity

//生成底部菜单共三步.
/*
*1.初始化Tabhost
*2.新建TabSpec
*3.添加TabSpec到TabHost
*/

FragmentTabHost fragmentTabHost = (FragmentTabHost) findViewById(android.R.id.tabhost);
fragmentTabHost.setup(this,getFragmentManager(),R.id.main_frameLayout);

//通过循环添加
for(int i=0;i<4;i++){
//newTabSpec的参数表示唯一表示符。用来确定那个被点击
TabHost.TabSpec tabSpec = fragmentTabHost.newTabSpec(tabSpecs[i]).setIndicator(View view);
//方法setIndicator()的参数即为显示的view
fragmentTabHost.addTab(tabSpec,fragmentArray[i],null);
//addTab的第二个参数即为该TabSpec对应的fragment
}
//取消每个条目之间的分割线
fragmentTabHost.getTabWidget().setDividerDrawable(android.R.color.white);
// 初始化 第一个条目被选中 通过唯一标识符确定
fragmentTabHost.setCurrentTabByTag(tabSpecs[0]);

具体给TabSpec设置的View是我自定义的view。此处不给出代码.
效果图:
Android底部菜单的两种实现方式