【声明】

欢迎转载,但请保留文章原始出处→_→

生命壹号:http://www.cnblogs.com/smyhvae/

文章来源:http://www.cnblogs.com/smyhvae/p/4463931.html

【正文】

实现APP首页底部Tab的切换已经见过四五种方式了,先来看运行的效果图吧:

今天我们就用RadioGroup的方法来实现以下。

【开发环境】

物理机版本:win 7旗舰版(64位)

IDE版本:Android Studio 1.2 preview

工程文件结构:(本文最后有源码)

  • HomeActivity.java:整个首页的界面
  • 四个Fragment.java:对应的四个Fragment界面
  • drawable文件夹中是对应tab和文字切换的状态
  • 剩下的xml文件就是对应的Activity和Fragment的布局文件了。

一、布局文件:

(1)activity_home.xml:HomeActivity的布局文件

 1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
2 xmlns:tools="http://schemas.android.com/tools"
3 android:layout_width="match_parent"
4 android:layout_height="match_parent"
5
6 tools:context=".MainActivity">
7
8 <!--tab上方的显示区域-->
9 <FrameLayout
10 android:id="@+id/mHomeContent"
11 android:layout_width="match_parent"
12 android:layout_height="match_parent"
13 android:layout_above="@+id/mHomeRadioGroup">
14
15 </FrameLayout>
16
17 <!--底下的四个tab-->
18 <RadioGroup
19 android:id="@+id/mHomeRadioGroup"
20 android:layout_width="match_parent"
21 android:layout_height="56dp"
22 android:orientation="horizontal"
23 android:layout_alignParentBottom="true"
24 android:background="@color/tab_bg" >
25
26 <RadioButton
27 android:id="@+id/mHomeHomeRb"
28 android:layout_width="0dp"
29 android:layout_height="wrap_content"
30 android:layout_weight="1"
31 android:button="@null"
32 android:gravity="center"
33 android:text="@string/home_home"
34 android:textColor="@drawable/selector_tab_text_color"
35 android:background="@color/tab_bg"
36 android:drawableTop="@drawable/selector_tab_home"
37 />
38
39 <RadioButton
40 android:id="@+id/mHomeFindRb"
41 android:layout_width="0dp"
42 android:layout_height="wrap_content"
43 android:layout_weight="1"
44 android:button="@null"
45 android:gravity="center"
46 android:text="@string/home_find"
47 android:textColor="@drawable/selector_tab_text_color"
48 android:background="@color/tab_bg"
49 android:drawableTop="@drawable/selector_tab_find"
50 />
51
52 <RadioButton
53 android:id="@+id/mHomeSearchRb"
54 android:layout_width="0dp"
55 android:layout_height="wrap_content"
56 android:layout_weight="1"
57 android:button="@null"
58 android:gravity="center"
59 android:text="@string/home_search"
60 android:textColor="@drawable/selector_tab_text_color"
61 android:background="@color/tab_bg"
62 android:drawableTop="@drawable/selector_tab_search"
63 />
64
65 <RadioButton
66 android:id="@+id/mHomeProfileRb"
67 android:layout_width="0dp"
68 android:layout_height="wrap_content"
69 android:layout_weight="1"
70 android:button="@null"
71 android:gravity="center"
72 android:text="@string/home_profile"
73 android:textColor="@drawable/selector_tab_text_color"
74 android:background="@color/tab_bg"
75 android:drawableTop="@drawable/selector_tab_profile"
76 android:checked="true"
77 />
78 </RadioGroup>
79 </RelativeLayout>

代码有点多,无非就是一个FrameLayout对应的是tab上方的显示区域,然后四个RadioButton凑成一组单选按钮放在RadioGroup当中。

13行:能够保证FrameLayout占据除开Tab之后的剩下的全部空间。

76行:android:checked="true"这个很重要,稍后在java代码中讲。

RadioButton的属性有点多,我们选取就选取第一个RadioButton进行讲解,上面的第一个RadioButton的属性摘抄如下:

 1         <RadioButton
2 android:id="@+id/mHomeHomeRb"
3 android:layout_width="0dp"
4 android:layout_height="wrap_content"
5 android:layout_weight="1"
6 android:button="@null"
7 android:gravity="center"
8 android:text="@string/home_home"
9 android:textColor="@drawable/selector_tab_text_color"
10 android:background="@color/tab_bg"
11 android:drawableTop="@drawable/selector_tab_home"
12 />

上方代码的解释如下:

05行:weight为1,并且width为0dp,是保证四个tab能均分宽度。

06行:去掉RadioButton的样式,也就是去掉那个小图标,然后radiobutton就只剩下文字了。

07行:让里面的内容居中

08行:显示的文字

10行:设置这个tab的背景色和整个radioGroup的背景色一样,不过,也可以删掉(删掉之后,在我的小米手机手机上的排版会有问题)

10行:在这个tab的上面添加对应的icon图标(很重要,就是有了这个属性,每个tab的图标才会不一样哦)。

(2)fragment_home.xml:fragment的布局文件

 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
2 xmlns:tools="http://schemas.android.com/tools"
3 android:layout_width="match_parent"
4 android:layout_height="match_parent"
5
6 tools:context=".MainActivity">
7
8 <TextView
9 android:layout_width="wrap_content"
10 android:layout_height="wrap_content"
11 android:text="HomeFragment"
12 android:textSize="20sp"/>
13
14 </LinearLayout>

其他三个fragment的布局文件都一样,代码就不贴出来了,本文最后有源码下载。

(3)selector_tab_home.xml:tab被选中时对应icon的状态

1 <?xml version="1.0" encoding="utf-8"?>
2 <selector xmlns:android="http://schemas.android.com/apk/res/android">
3
4 <item android:drawable="@mipmap/tab_home_selected" android:state_pressed="false" android:state_selected="true" />
5 <item android:drawable="@mipmap/tab_home_selected" android:state_checked="true" android:state_pressed="false" />
6 <item android:drawable="@mipmap/tab_home_nomal" />
7
8
9 </selector>

06行是默认的状态。

其他三个tab的状态都差不多,代码就不贴出来了,本文最后有源码下载。

(4)selector_tab_text_color.xml:tab中的文字被选中时的状态

1 <?xml version="1.0" encoding="utf-8"?>
2 <selector xmlns:android="http://schemas.android.com/apk/res/android">
3
4 <item android:color="@color/white" android:state_pressed="false" android:state_selected="true" />
5 <item android:color="@color/white" android:state_checked="true" android:state_pressed="false" />
6 <item android:color="@color/black" />
7
8
9 </selector>

06行:默认的文字颜色是黑色,被切换时是白色。

二、Java代码:

(1)HomeActivity.java:

  1 package com.smyhvae.radiogrouptabdemo;
2
3 import android.os.Bundle;
4 import android.support.v4.app.Fragment;
5 import android.support.v4.app.FragmentActivity;
6 import android.support.v4.app.FragmentStatePagerAdapter;
7 import android.view.Window;
8 import android.widget.FrameLayout;
9 import android.widget.RadioButton;
10 import android.widget.RadioGroup;
11
12 import com.smyhvae.radiogrouptabdemo.fragment.FindFagment;
13 import com.smyhvae.radiogrouptabdemo.fragment.HomeFagment;
14 import com.smyhvae.radiogrouptabdemo.fragment.ProfileFagment;
15 import com.smyhvae.radiogrouptabdemo.fragment.SearchFagment;
16
17
18 /**
19 * Created by smyhvae on 2015/4/28.
20 *
21 */
22
23 public class HomeActivity extends FragmentActivity {
24 private FrameLayout mHomeContent;
25 private RadioGroup mHomeRadioGroup;
26 private RadioButton mHomeHomeRb;
27 private RadioButton mHomeFindRb;
28 private RadioButton mHomeSearchRb;
29 private RadioButton mHomeProfileRb;
30
31 static final int NUM_ITEMS = 4;//一共四个fragment
32
33 @Override
34 protected void onCreate(Bundle savedInstanceState) {
35 super.onCreate(savedInstanceState);
36 requestWindowFeature(Window.FEATURE_NO_TITLE);
37 setContentView(R.layout.activity_home);
38 initView();
39 initData();
40 }
41
42 protected void initView() {
43 mHomeContent = (FrameLayout) findViewById(R.id.mHomeContent); //tab上方的区域
44 mHomeRadioGroup = (RadioGroup) findViewById(R.id.mHomeRadioGroup); //底部的四个tab
45 mHomeHomeRb = (RadioButton) findViewById(R.id.mHomeHomeRb);
46 mHomeFindRb = (RadioButton) findViewById(R.id.mHomeFindRb);
47 mHomeSearchRb = (RadioButton) findViewById(R.id.mHomeSearchRb);
48 mHomeProfileRb = (RadioButton) findViewById(R.id.mHomeProfileRb);
49
50 //监听事件:为底部的RadioGroup绑定状态改变的监听事件
51 mHomeRadioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
52 @Override
53 public void onCheckedChanged(RadioGroup group, int checkedId) {
54 int index = 0;
55 switch (checkedId) {
56 case R.id.mHomeHomeRb:
57 index = 0;
58 break;
59 case R.id.mHomeFindRb:
60 index = 1;
61 break;
62 case R.id.mHomeSearchRb:
63 index = 2;
64 break;
65 case R.id.mHomeProfileRb:
66 index = 3;
67 break;
68 }
69 //通过fragments这个adapter还有index来替换帧布局中的内容
70 Fragment fragment = (Fragment) fragments.instantiateItem(mHomeContent, index);
71 //一开始将帧布局中 的内容设置为第一个
72 fragments.setPrimaryItem(mHomeContent, 0, fragment);
73 fragments.finishUpdate(mHomeContent);
74
75 }
76 });
77 }
78
79
80 //第一次启动时,我们让mHomeHomeRb这个radiobutton处于选中状态。
81 // 当然了,在这之前,先要在布局文件中设置其他的某一个radiobutton(只要不是mHomeHomeRb就行)
82 // 的属性为android:checked="true",才会出发下面的这个check方法切换到mHomeHomeRb
83 @Override
84 protected void onStart() {
85 super.onStart();
86 mHomeRadioGroup.check(R.id.mHomeHomeRb);
87 }
88
89 //用adapter来管理四个Fragment界面的变化。注意,我这里用的Fragment都是v4包里面的
90 FragmentStatePagerAdapter fragments = new FragmentStatePagerAdapter(getSupportFragmentManager()) {
91
92 @Override
93 public int getCount() {
94 return NUM_ITEMS;//一共有四个Fragment
95 }
96
97 //进行Fragment的初始化
98 @Override
99 public Fragment getItem(int i) {
100 Fragment fragment = null;
101 switch (i) {
102 case 0://首页
103 fragment = new HomeFagment();
104 break;
105 case 1://发现
106 fragment = new FindFagment();
107 break;
108
109 case 2://搜索
110 fragment = new SearchFagment();
111 break;
112
113 case 3://我的
114 fragment = new ProfileFagment();
115 break;
116 default:
117 new HomeFagment();
118 break;
119 }
120
121 return fragment;
122 }
123 };
124
125 protected void initData() {
126
127 }
128
129 }

代码注释已经很详细了。

尤其要注意的是第80行的注释,为了让app第一次启动时,默认就让第一个tab处于选中状态,我们现在activity_home.xml(76行)中让剩下的随便哪个radioButton的属性为checked,然后再重写上方java代码中的onStart方法(86行)。

(2)HomeFragment.java:

 1 package com.smyhvae.radiogrouptabdemo.fragment;
2
3 import android.os.Bundle;
4 import android.support.v4.app.Fragment;
5 import android.view.LayoutInflater;
6 import android.view.View;
7 import android.view.ViewGroup;
8
9 import com.smyhvae.radiogrouptabdemo.R;
10
11
12 /**
13 * Created by smyh on 2015/4/28.
14 */
15 public class HomeFagment extends Fragment {
16 @Override
17 public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
18 View view = LayoutInflater.from(getActivity()).inflate(R.layout.fragment_home, null);
19 return view;
20 }
21
22 //重写setMenuVisibility方法,不然会出现叠层的现象
23 @Override
24 public void setMenuVisibility(boolean menuVisibile) {
25 super.setMenuVisibility(menuVisibile);
26 if (this.getView() != null) {
27 this.getView().setVisibility(menuVisibile ? View.VISIBLE : View.GONE);
28 }
29 }
30
31 }

剩下三个Fragment的java代码是一样的,就不贴出来了,详见本文最后的源码。

【工程文件】

2015-04-28-RadioGroupTabDemo

RadioGroup实现导航栏的更多相关文章

  1. Android底部导航栏——FrameLayout + RadioGroup

    原创文章,转载请注明出处http://www.cnblogs.com/baipengzhan/p/6285881.html Android底部导航栏有多种实现方式,本文详细介绍FrameLayout ...

  2. Android底部导航栏创建——ViewPager + RadioGroup

    原创文章,引用请注明出处:http://www.cnblogs.com/baipengzhan/p/6270201.html Android底部导航栏有多种实现方式,本文详解其中的ViewPager ...

  3. [Android]--RadioGroup+RadioButton实现底部导航栏

    RadioGroup+RadioButton组合方式打造简单实用的底部导航栏 代码块: <?xml version="1.0" encoding="utf-8&qu ...

  4. Android应用底部导航栏(选项卡)实例

    现在很多android的应用都采用底部导航栏的功能,这样可以使得用户在使用过程中随意切换不同的页面,现在我采用TabHost组件来自定义一个底部的导航栏的功能. 我们先看下该demo实例的框架图: 其 ...

  5. 使用TabLayout快速实现一个导航栏

    在没有Material Design的年代,要实现一个类似微信主页面的效果,我们有以下几种解决方案: 1.Fragment + ViewPager  +  RadioGroup自定义固定导航条 2.F ...

  6. 二、Fragment+RadioButton实现底部导航栏

    在App中经常看到这样的tab底部导航栏   那么这种效果是如何实现,实现的方式有很多种,最常见的就是使用Fragment+RadioButton去实现.下面我们来写一个例子 首先我们先在activi ...

  7. Android (争取做到)最全的底部导航栏实现方法

    本文(争取做到)Android 最全的底部导航栏实现方法. 现在写了4个主要方法. 还有一些个人感觉不完全切题的方法也会简单介绍一下. 方法一. ViewPager + List<View> ...

  8. Android UI-仿微信底部导航栏布局

    现在App基本的标配除了侧滑菜单,还有一个就是底部导航栏,常见的聊天工具QQ,微信,购物App都有底部导航栏,用户可以随便切换看不同的内容,说是情怀也好,用户体验也罢.我们开发的主要的还是讲的是如何如 ...

  9. Android商城开发系列(三)——使用Fragment+RadioButton实现商城底部导航栏

    在商城第一篇的开篇当中,我们看到商城的效果图里面有一个底部导航栏效果,如下图所示: 今天我们就来实现商城底部导航栏,最终效果图如下所示:   那么这种效果是如何实现,实现的方式有很多种,最常见的就是使 ...

随机推荐

  1. 如何搞定IE+google双内核的360浏览器表单自动回填兼容问题

    最近开发中碰到一个关于表单问题,在用户提交表单时候浏览器会提示是否保存帐号 如果点击保存,在退出帐号切换其他帐号时,浏览器会自动为表单填充数据,为了解决这个自动填充问题时, 主要分2个思路来解决,一个 ...

  2. C语言中,头文件和源文件的关系(转)

    简单的说其实要理解C文件与头文件(即.h)有什么不同之处,首先需要弄明白编译器的工作过程,一般说来编译器会做以下几个过程: 1.预处理阶段 2.词法与语法分析阶段 3.编译阶段,首先编译成纯汇编语句, ...

  3. Wakez计算与压缩的思考

    大部分人认为,比尔盖茨在1981年说过这样一句话:640K ought to be enough for anybody.(640个kB对任何人来说都应该足够了).不过后来比尔盖茨否认自己说过这句话. ...

  4. Vue.js与MVVM

    MVVM 是Model-View-ViewModel 的缩写,它是一种基于前端开发的架构模式,其核心是提供对View 和 ViewModel 的双向数据绑定,这使得ViewModel 的状态改变可以自 ...

  5. C++开始前篇,深入编译链接(3)

    一,COMMON块 什么是COMMON块,这是一种机制,早期的Fortran没有动态分配空间的机制,程序员必须事先声明它所需要的临时使用空间的大小.Fortran把这种空间叫做COMMON块,当不同的 ...

  6. 使用Selector改变TextView的字体颜色textColor的方法

    先上Selector文件,名字为singer_fragment_top_text_style.xml, <?xml version="1.0" encoding=" ...

  7. 【体系结构】动态调度算法:记分牌算法和tomasulo算法

    记分牌和tomasulo算法 动态调度: 通过硬件在程序执行时重新安排代码的执行序列来减少竞争引起的流水线停顿时间 动态调度流水线具备以下功能: (1)允许按序取多条指令和发射多条指令----取指(I ...

  8. Problem with "AnyConnect was not able to establish connection to the specified secure gateway."

    Cisco的VPN客户端最近报"AnyConnect was not able to establish connection to the specified secure gateway ...

  9. Hive的三种安装方式(内嵌模式,本地模式远程模式)

    一.安装模式介绍:     Hive官网上介绍了Hive的3种安装方式,分别对应不同的应用场景.     1.内嵌模式(元数据保村在内嵌的derby种,允许一个会话链接,尝试多个会话链接时会报错)   ...

  10. F#之旅9 - 正则表达式

    今天,cozy群有个群友发了条正则,问正则匹配相关的问题.虽然他的问题用html selector去处理可能更好,但是我也再一次发现:我忘了正则怎么写的了! 忘掉正则是有原因的,这篇文章会简单记录下F ...