FragmentTabHost+RadioButton实现底部导航栏(带小红点提示)

来源:互联网 发布:unity3d ui制作 编辑:程序博客网 时间:2024/06/09 21:42

先上效果图

这里写图片描述

关于实现小红点的方法,网上很多人建议用badgeView来实现,我当初做项目也是用它来实现的,那时候底部有5个tab,没发现问题,现在当我想用3个来展示的时候,却出现了小红点跟图片距离很大,效果不好。关于用badgeview实现,建议底部tab4个以上才用。下面我直接就用布局来实现了。


用FragmentTabHost+RadioButton组合来实现底部导航栏效果,实际上就是利用FragmentTabHost来切换Fragment,然后tab的点击就交给RadioButton去处理。


开始也是要先准备底部tab的图片资源,小红点的xml文件,和一个小红点带文字的背景xml文件,当然也可以用图片来实现,还有就是三个对应的fragment。


带文字的背景bg_tab_tips.xml文件代码如下:

<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android"><solid android:color="@color/red"></solid><corners android:radius="12dp"></corners><padding android:bottom="1dp" android:left="1dp"   android:right="1dp"    android:top="1dp"></padding></shape>

小红点bg_tab_roundtip.xml文件代码如下:

?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android"android:shape="oval"><solid android:color="@color/red"></solid><corners android:radius="5dp"></corners><size android:width="10dp" android:height="10dp"></size></shape>------------------------------------->在写界面代码之前,先上布局文件(基本小红点的实现就在布局里写好了)    <?xml version="1.0" encoding="utf-8"?>    <LinearLayout   xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+id/activity_main"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:fitsSystemWindows="true"    android:orientation="vertical"><!--装载fragment的容器,也可以用其它的布局--><LinearLayout    android:id="@+id/Container"    android:layout_width="match_parent"    android:layout_height="wrap_content"    android:layout_weight="1"    android:orientation="vertical" /><!-- 只用于切换fragment,由radiobutton实现点击监听--><com.wenthkim.pro.fragment_radiobutton.widget.FragmentTabHost    android:id="@+id/tabHost"    android:layout_width="match_parent"    android:layout_height="wrap_content"    android:visibility="gone" /><LinearLayout    android:layout_width="match_parent"    android:layout_height="wrap_content"    android:layout_gravity="bottom"    android:background="#ffffff"    android:fitsSystemWindows="true">    <!-- 首页的tab-->    <FrameLayout        android:layout_width="0dp"        android:layout_height="wrap_content"        android:layout_weight="1"        android:background="@null">        <LinearLayout            android:layout_width="match_parent"            android:layout_height="match_parent"            android:gravity="bottom|center">            <RadioButton                android:id="@+id/rdoBtn_home"                android:layout_width="match_parent"                android:layout_height="wrap_content"                android:layout_gravity="center"                android:background="@null"                android:button="@null"                android:drawableTop="@drawable/home_selector"                android:gravity="center"                android:paddingTop="3dp"                android:text="首页"                android:textColor="@drawable/tabtext_selector"                android:textSize="12sp" />        </LinearLayout>        <TextView            android:id="@+id/tv1"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_gravity="top|center_horizontal"            android:layout_marginLeft="15dp"            android:background="@drawable/bg_tab_tips"            android:padding="2dp"            android:text="99"            android:textColor="#ffffff"            android:visibility="visible" />    </FrameLayout>    <!--  购物车的tab-->    <FrameLayout        android:layout_width="0dp"        android:layout_height="wrap_content"        android:layout_weight="1"        android:background="@null">        <LinearLayout            android:layout_width="match_parent"            android:layout_height="match_parent"            android:gravity="bottom|center">            <RadioButton                android:id="@+id/rdoBtn_shopcar"                android:layout_width="match_parent"                android:layout_height="wrap_content"                android:layout_gravity="center"                android:background="@null"                android:button="@null"                android:drawableTop="@drawable/shopcar_selector"                android:gravity="center"                android:paddingTop="3dp"                android:text="购物车"                android:textColor="@drawable/tabtext_selector"                android:textSize="12sp" />        </LinearLayout>        <TextView            android:id="@+id/tv2"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_gravity="top|center_horizontal"            android:layout_marginLeft="10dp"            android:padding="3dp"            android:textSize="10sp"            android:visibility="visible" />    </FrameLayout>    <!--android:drawableRight="@drawable/bg_tab_roundtip"-->    <!-- 我的tab-->    <FrameLayout        android:layout_width="0dp"        android:layout_height="wrap_content"        android:layout_weight="1"        android:background="@null">        <LinearLayout            android:layout_width="match_parent"            android:layout_height="match_parent"            android:gravity="bottom|center">            <RadioButton                android:id="@+id/rdoBtn_mine"                android:layout_width="match_parent"                android:layout_height="wrap_content"                android:layout_gravity="center"                android:background="@null"                android:button="@null"                android:drawableTop="@drawable/mine_selector"                android:gravity="center"                android:paddingTop="3dp"                android:text="我的"                android:textColor="@drawable/tabtext_selector"                android:textSize="12sp" />        </LinearLayout>        <TextView            android:id="@+id/tv3"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_gravity="top|center_horizontal"            android:layout_marginLeft="10dp"            android:padding="3dp"            android:visibility="visible" />    </FrameLayout></LinearLayout></LinearLayout>

直接上主界面代码了,如下:
public class MainActivity extends AppCompatActivity implements CompoundButton.OnCheckedChangeListener {

private FragmentTabHost tabhost;private Class[] fragments = new Class[]{        HomeFragment.class, ShopCarFragment.class, MineFragment.class};private BadgeView bvShop;private RadioButton rdobtnHome;private RadioButton rdobtnCar;private RadioButton rdobtnMine;private int firstState = 0;//第一次选中第一个private TextView tv_tip;@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    initViews();    initTabs();}/** * 初始化每一个tab */private void initTabs() {    tabhost.setup(MainActivity.this, getSupportFragmentManager(), R.id.Container);    for (int i = 0; i < fragments.length; i++) {       /* radiobutton+fragmenttabhost组合实际是利用fragmenttabhost来切换       * fragment,而radiobutton则作为点击监听器       * */        tabhost.addTab(tabhost.newTabSpec(String.valueOf(i)).setIndicator(String.valueOf(i)),                fragments[i], null);    }    //默认情况下选择第一个    tabhost.setCurrentTab(0);}/** * 初始化控件 */private void initViews() {    tabhost = (FragmentTabHost) findViewById(R.id.tabHost);    rdobtnHome = (RadioButton) findViewById(R.id.rdoBtn_home);    rdobtnCar = (RadioButton) findViewById(R.id.rdoBtn_shopcar);    rdobtnMine = (RadioButton) findViewById(R.id.rdoBtn_mine);    rdobtnHome.setOnCheckedChangeListener(this);    rdobtnCar.setOnCheckedChangeListener(this);    rdobtnMine.setOnCheckedChangeListener(this);    rdobtnHome.setChecked(true);    tv_tip = (TextView) findViewById(R.id.tv2);    Drawable drawable = getResources().getDrawable(R.drawable.bg_tab_roundtip);    /// 这一步必须要做,否则不会显示.    drawable.setBounds(0, 0, drawable.getMinimumWidth(), drawable.getMinimumHeight());    tv_tip.setCompoundDrawables(null, null, drawable, null);}/** *  重置radioButton状态  * @param state 第几tab被点击 */private void setTab(int state) {    //如果点击的是当前选中的tab就不处理    if (firstState == state)        return;    firstState = state;    rdobtnHome.setChecked(false);    rdobtnCar.setChecked(false);    rdobtnMine.setChecked(false);    switch (state) {        case 0:            rdobtnHome.setChecked(true);            tabhost.setCurrentTab(0);            break;        case 1:            rdobtnCar.setChecked(true);            tabhost.setCurrentTab(1);            break;        case 2:            rdobtnMine.setChecked(true);            tabhost.setCurrentTab(2);            break;    }}@Overridepublic void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {    /*只要chedk有变化都会进入 先执行第一个变化的,即被点击那个*/    if (isChecked) {        switch (buttonView.getId()) {            case R.id.rdoBtn_home:                setTab(0);                break;            case R.id.rdoBtn_shopcar:                setTab(1);                break;            case R.id.rdoBtn_mine:                setTab(2);                break;        }    }}}

说一下要注意的一些地方吧

1.就是实现小红点,我们要用代码设置textview的drawableleft的时候,一定要加上这句代码,否则它显示不出来,当然如果没特殊需求的话,可以直接在布局里面设置就好。
drawable.setBounds(0, 0, drawable.getMinimumWidth(), drawable.getMinimumHeight());

2.还有就是监听radiobutton的被选中状态,由于我们没有用RadioGroup来实现的,因为用RadioGroup做不到我们想要的效果,所以这里是实现CompoundButton.OnCheckedChangeListener这个接口的,然后重写它那个方法要注意一下,该方法如下:

@Overridepublic void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {    /*只要check有变化都会进入 先执行第一个变化的,即被点击那个*/    if (isChecked) {        switch (buttonView.getId()) {            case R.id.rdoBtn_home:                setTab(0);                break;            case R.id.rdoBtn_shopcar:                setTab(1);                break;            case R.id.rdoBtn_mine:                setTab(2);                break;        }    }}

因为每一次不同的点击,该方法都会调用两次,就是每一个radiobutton的焦点发生变化该方法就被调用,所以要先判断isChecked是否为true(true即为被选中的那个tab)才进行相应的操作。

项目github地址

0 0