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

先上效果图

这里写图片描述

关于实现小红点的方法,网上很多人建议用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;
@Override
protected 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;
    }
}

@Override
public 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这个接口的,然后重写它那个方法要注意一下,该方法如下:

@Override
public 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地址

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值