Android自定义控件----RadioGroup实现APP首页底部Tab的切换

?【声明】

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

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

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

联系方式:[email protected]

【正文】

实现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

时间: 2024-08-05 19:36:00

Android自定义控件----RadioGroup实现APP首页底部Tab的切换的相关文章

首页-底部Tab导航(菜单栏)的实现:FragmentTabHost+ViewPager+Fragment

前言 Android开发中使用底部菜单栏的频次非常高,主要的实现手段有以下: - TabWidget - 隐藏TabWidget,使用RadioGroup和RadioButton - FragmentTabHost - 5.0以后的TabLayout - 最近推出的 Bottom navigation 今天带大家来探索下如何用Fragment+FragmentTabHost++ViewPager 实现底部菜单栏 目录 总体设计思路 Fragment:存放不同选项的页面内容 FragmentTab

Fragment实现底部Tab,切换可保存状态

activity_main.xml 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_pare

Android底部Tab页基于ViewPager的实现

在众多主流App中,包括QQ,微信等,为了和ios的UI保持统一,很多App使用的都是底部导航,当然在Android中也并不反对这种设计.这篇文章使用ViewPager实现这种效果.首先看实现效果图吧.效果图中包含了ViewPager的嵌套. 在讨论实现之前,我们先来回忆一下,之前我们是如何实现的. 之前的实现方法,我们无法是先进行布局,再编写逻辑.而布局,底部有一定高度的Tab,一般由4个或者5个,也有3个的,具体视应用而定,而Tab上方则是一个FrameLayout,用于作为fragment

【原创】android——Tabhost 自定义tab+底部实现+intent切换内容

1,实现tabhost自定义格式,再此仅仅显示背景和文字,效果图预览:(底边栏所示) (图片变形) 2,xml配置 activity_user的XML配置  1 <TabHost xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:id="@+id/tabhost&qu

Android官方底部Tab栏设计规范

上一篇<仿微信底部Tab栏>中粗略的讲了下底部Tab栏的封装,不少同学在实际运用中发现了一些问题,比如我demo中的title用了actionbar,所以如果新建的Activity的Theme不包含actionbar就回出现空指针:再比如假如底部的Tab对应的并不全都是Fragment,而是一部分Fragment,一部分Activity,就不适用了,但办法总比困难多,这个也是可以解决的:还有一个很常见的需求,就是底部有些Tab可能会有个小红点,之前的Demo并没有把这些问题包含进去,后续有时间

Android典型界面设计——FragmentTabHost+Fragment实现底部tab切换

Android典型界面设计——FragmentTabHost+Fragment实现底部tab切换 Android学习笔记:TabHost 和 FragmentTabHost

【Android自定义控件】支持多层嵌套RadioButton的RadioGroup

前言 非常喜欢用RadioButton+RadioGroup做Tabs,能自动处理选中等效果,但是自带的RadioGroup不支持嵌套RadioButton(从源码可看出仅仅是判断子控件是不是RadioButton),本文参考RadioGroup修改了一个支持嵌套CompoundButton的控件,非常实用. 声明 欢迎转载,但请保留文章原始出处:) 博客园:http://www.cnblogs.com 农民伯伯: http://over140.cnblogs.com 正文 /** * 支持嵌套

封装实践——打造微信底部tab栏

目前市面上很多App都采用底部一个Tab栏,管理四到五个Tab,然后选择切换页面的方式的设计,这虽然不太符合metro design,但确是一个不容易出错而又符合国人使用习惯的设计方式.比如微信,支付宝,网易新闻,简书等都采用这种设计.而所谓封装一定是基于某种确定的业务需求,所以针对上述的通用设计方式,我们可以做一个比较理想化的封装. 为什么要做封装 你可能会觉得,这就是一个选择切换嘛,我只要做些if else判断就好了.但是Tab栏一般用在首页,业务逻辑代码量就不用说了,如果这时候不想被各种i

多种多样的App主界面Tab实现方法

看了一下App主界面Tab实现方法,总结一下: 再看看实现的效果图:                            第一种:ViewPager实现Tab: 思路:1.布局方面实现顶层和底层布局,中间是ViewPager实现的.中间是四个布局实现的,List<View>                 2.实现:setOnPageChangeListener内部类                3.需要一个适配器:PagerAdapter 源代码如下: <span style=&q