您的位置:首页 > 其它

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

2016-08-26 00:12 549 查看
先上效果图



关于实现小红点的方法,网上很多人建议用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地址
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: