前言
以前都是使用TabHost组件来实现底部标签导航,由于其可定制性较差,所以实现起来比较麻烦。今天来介绍一种使用RadioButton+Fragment轻松实现微信底部标签菜单的效果,先上图:
现在分步讲解整个实现过程:
1、布局代码
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android">
<FrameLayout
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" >
</FrameLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom" >
<RadioGroup
android:id="@+id/rg"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<RadioButton
android:id="@+id/message"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@drawable/bg_drawable"
android:text="消息"
android:checked="true"
android:button="@null"
android:gravity="center_horizontal"
android:drawableTop="@drawable/ic_launcher"
/>
<RadioButton
android:id="@+id/friend"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@drawable/bg_drawable"
android:text="好友"
android:button="@null"
android:gravity="center_horizontal"
android:drawableTop="@drawable/ic_launcher"
/>
<RadioButton
android:id="@+id/setting"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@drawable/bg_drawable"
android:text="设置"
android:button="@null"
android:gravity="center_horizontal"
android:drawableTop="@drawable/ic_launcher"
/>
</RadioGroup>
</LinearLayout>
</LinearLayout>
布局文件比较简单,但有几个属性需要拿出来重点介绍下:
android:drawableTop:该属性来自于TextView(派生出了Button、RadioButton),真的太强大了,可以直接在文本内容上部添加一个图片,只要一个属性轻松解决底部图标设置的问题。当然他的兄弟属性还有:drawableBottom、drawableStart/drawableEnd、drawableLeft/drawableRight,都是在文本的某个位置设置一张图。
android:button="@null":该属性可以隐藏掉单选按钮左边默认的圆形按钮,从而让我们的一组单选按钮看起来化身为了“普通按钮”,但是这组按钮,当你check选中了某个按钮的时候,其他按钮自动变为unchecked状态,所以这个时候可以通过为他们设置background属性来改变选中状态的按钮背景,如下是我在drawable文件夹设置的bg_drawable内容:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_checked="true" android:drawable="@drawable/dark"></item>
<item android:state_checked="false" android:drawable="@drawable/light"></item>
</selector>
2、单选按钮对应的Fragment
3个单选按钮对应的3个Fragment都很简单,都只包含一个简单的文本框。实际开发当中以具体业务为准,本文只是讲解功能。
MessageFragment的布局文件:
<?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="消息"
/>
</LinearLayout>
MessageFragment.java文件:
package com.example.radiobuttontabdemo;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class MessageFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view =inflater.inflate(R.layout.message_fragment, container, false);
return view;
}
}
FriendFragment、SettingFragment的布局文件以及java代码类似。
3、MainActivity.java
代码很简单,注释讲解也很详细,具体代码见下:
package com.example.radiobuttontabdemo;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentTransaction;
import android.widget.RadioGroup;
public class MainActivity extends FragmentActivity {
private RadioGroup radioGroup;
private MessageFragment messageFragment;
private FriendFragment friendFragment;
private SettingFragment settingFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 默认在内容区显示消息Fragment
setTabSelection(0);
radioGroup=(RadioGroup) findViewById(R.id.rg);
// 为radioGroup设置了选中状态改变的监听器
radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup arg0, int id) {
// TODO Auto-generated method stub
switch (id) {
case R.id.message:
setTabSelection(0);
break;
case R.id.friend:
setTabSelection(1);
break;
case R.id.setting:
setTabSelection(2);
break;
default:
break;
}
}
});
}
/**
* 根据传入的index参数来设置选中的tab页。
*
* @param index
* 每个tab页对应的下标。0表示消息,1表示好友,2表示设置
*/
private void setTabSelection(int index) {
// 开启一个Fragment事务
FragmentTransaction transaction =getSupportFragmentManager().beginTransaction();
// 先隐藏掉所有的Fragment,以防止有多个Fragment显示在界面上的情况
hideFragment(transaction);
switch (index) {
// 点击消息tab
case 0:
if (messageFragment == null) {
// 如果MessageFragment为空,则创建一个并添加到界面上
messageFragment = new MessageFragment();
transaction.add(R.id.content, messageFragment);
} else {
// 如果MessageFragment不为空,则直接将它显示出来
transaction.show(messageFragment);
}
break;
// 点击好友tab
case 1:
if (friendFragment == null) {
// 如果friendFragment为空,则创建一个并添加到界面上
friendFragment = new FriendFragment();
transaction.add(R.id.content, friendFragment);
} else {
// 如果friendFragment不为空,则直接将它显示出来
transaction.show(friendFragment);
}
break;
// 点击设置tab
case 2:
if (settingFragment == null) {
// 如果settingFragment为空,则创建一个并添加到界面上
settingFragment = new SettingFragment();
transaction.add(R.id.content, settingFragment);
} else {
// 如果settingFragment不为空,则直接将它显示出来
transaction.show(settingFragment);
}
break;
}
transaction.commit();
}
/**
* 将所有的Fragment都置为隐藏状态。
*
* @param transaction
* 用于对Fragment执行操作的事务
*/
private void hideFragment(FragmentTransaction transaction) {
if (messageFragment != null) {
transaction.hide(messageFragment);
}
if (friendFragment != null) {
transaction.hide(friendFragment);
}
if (settingFragment != null) {
transaction.hide(settingFragment);
}
}
}
好了, 整篇文章的讲解就到这里了,使用RadioButton+Fragment实现微信底部标签菜单真的不难,梳理清思路,很好理解。