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

【声明】 

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

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

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

联系方式:[email protected] 

 

【正文】

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

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

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

 

【开发环境】

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

IDE版本:Android Studio 1.2 preview

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

70d49874-8327-4690-9882-eec70703bfbe

  • 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

 

你可能感兴趣的:(android)