前言

本篇博客要分享的一个UI效果——实现底部切换标签,想必大家在一些应用上面遇到过这种效果了,最典型的就是微信了,可以左右滑动切换页面,也可以点击标签页滑动页面,它们是如何实现的呢,本篇博客为了简单只介绍如何实现点击底部切换标签页。

先来看看我们想实现的效果图:

Android UI-实现底部切换标签(fragment)_xml

这样的页面实现起来其实很简单的,首先我们从布局入手:

分为三部分

第一部分:顶部导航栏布局

第二部分:中部显示内容布局

第三部分:底部标签布局


/BottomTabDemo/res/layout/activity_main.xml

[html]  view plain  copy

1. <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"  
2. android:layout_width="match_parent"  
3. android:layout_height="match_parent" >  
4.   
5. <RelativeLayout  
6. android:id="@+id/rl_main"  
7. android:layout_width="match_parent"  
8. android:layout_height="match_parent" >  
9.   
10. <!-- 顶部 -->  
11.   
12. <RelativeLayout  
13. android:id="@+id/top_tab"  
14. android:layout_width="match_parent"  
15. android:layout_height="50dip"  
16. android:background="@color/topbar_bg" >  
17.   
18. <ImageView  
19. android:id="@+id/iv_logo"  
20. android:layout_width="wrap_content"  
21. android:layout_height="wrap_content"  
22. android:layout_centerInParent="true"  
23. android:focusable="false"  
24. android:src="@drawable/zhidao_logo"  
25. android:contentDescription="@null" />  
26.   
27. </RelativeLayout>  
28.   
29. <!-- 底部tab -->  
30.   
31. <LinearLayout  
32. android:id="@+id/ll_bottom_tab"  
33. android:layout_width="match_parent"  
34. android:layout_height="54dp"  
35. android:layout_alignParentBottom="true"  
36. android:gravity="center_vertical"  
37. android:orientation="horizontal"   
38. android:baselineAligned="true">  
39.   
40. <RelativeLayout  
41. android:id="@+id/rl_know"  
42. android:layout_width="0dp"  
43. android:layout_height="wrap_content"  
44. android:layout_weight="1.0" >  
45.   
46. <ImageView  
47. android:id="@+id/iv_know"  
48. android:layout_width="wrap_content"  
49. android:layout_height="wrap_content"  
50. android:layout_centerHorizontal="true"  
51. android:src="@drawable/btn_know_nor"   
52. android:contentDescription="@null"/>  
53.   
54. <TextView  
55. android:id="@+id/tv_know"  
56. android:layout_width="wrap_content"  
57. android:layout_height="wrap_content"  
58. android:layout_below="@id/iv_know"  
59. android:layout_centerHorizontal="true"  
60. android:text="@string/bottom_tab_know"  
61. android:textColor="@color/bottomtab_normal"  
62. android:textSize="12sp" />  
63. </RelativeLayout>  
64.   
65. <RelativeLayout  
66. android:id="@+id/rl_want_know"  
67. android:layout_width="0dp"  
68. android:layout_height="wrap_content"  
69. android:layout_weight="1.0" >  
70.   
71. <ImageView  
72. android:id="@+id/iv_i_want_know"  
73. android:layout_width="wrap_content"  
74. android:layout_height="wrap_content"  
75. android:layout_centerHorizontal="true"  
76. android:src="@drawable/btn_wantknow_nor"  
77. android:contentDescription="@null" />  
78.   
79. <TextView  
80. android:id="@+id/tv_i_want_know"  
81. android:layout_width="wrap_content"  
82. android:layout_height="wrap_content"  
83. android:layout_below="@+id/iv_i_want_know"  
84. android:layout_centerHorizontal="true"  
85. android:text="@string/bottom_tab_wantknow"  
86. android:textColor="@color/bottomtab_normal"  
87. android:textSize="12sp" />  
88. </RelativeLayout>  
89.   
90. <RelativeLayout  
91. android:id="@+id/rl_me"  
92. android:layout_width="0dp"  
93. android:layout_height="wrap_content"  
94. android:layout_weight="1.0" >  
95.   
96. <ImageView  
97. android:id="@+id/iv_me"  
98. android:layout_width="wrap_content"  
99. android:layout_height="wrap_content"  
100. android:layout_centerHorizontal="true"  
101. android:src="@drawable/btn_my_nor"  
102. android:contentDescription="@null" />  
103.                   
104.   
105. <TextView  
106. android:id="@+id/tv_me"  
107. android:layout_width="wrap_content"  
108. android:layout_height="wrap_content"  
109. android:layout_below="@+id/iv_me"  
110. android:layout_centerHorizontal="true"  
111. android:text="@string/bottom_tab_my"  
112. android:textColor="@color/bottomtab_normal"  
113. android:textSize="12sp" />  
114. </RelativeLayout>  
115. </LinearLayout>  
116.   
117. <!-- 内容部分, fragment切换 -->  
118.   
119. <LinearLayout  
120. android:id="@+id/content_layout"  
121. android:layout_width="match_parent"  
122. android:layout_height="match_parent"  
123. android:layout_above="@+id/line"  
124. android:layout_below="@+id/top_tab"  
125. android:orientation="vertical" >  
126. </LinearLayout>  
127.   
128. <View  
129. android:id="@+id/line"  
130. android:layout_width="match_parent"  
131. android:layout_height="1dp"  
132. android:layout_above="@id/ll_bottom_tab"  
133. android:background="@color/line" />  
134. </RelativeLayout>  
135.       
136. </FrameLayout>

我们会发现,初始的时候是选中第一个标签页,图片和字体的颜色区别于另外两个标签页,所以我们要做的就是切换标签的时候,就改变标签的状态

主要改两个内容:

  • 图片
  • 文字颜色

然后我们切换标签显示的是不同的Fragment,这里我们有三个Fragment,所以我们定义三个不同的Fragment界面:

/BottomTabDemo/src/com/xiaowu/bottomtab/demo/ZhidaoFragment.java

/BottomTabDemo/src/com/xiaowu/bottomtab/demo/IWantKnowFragment.java

/BottomTabDemo/src/com/xiaowu/bottomtab/demo/MeFragment.java

每个Fragment对应不同的布局文件:

/BottomTabDemo/res/layout/main_tab1_fragment.xml

/BottomTabDemo/res/layout/main_tab2_fragment.xml

/BottomTabDemo/res/layout/main_tab3_fragment.xml


ok,这些定义好之后,我们就在主界面上编写切换的代码了,如何对Fragment进行切换呢,定义以下方法:

[java]  view plain  copy

1. /**
2.      * 添加或者显示碎片
3.      * 
4.      * @param transaction
5.      * @param fragment
6.      */  
7. private void addOrShowFragment(FragmentTransaction transaction,  
8.             Fragment fragment) {  
9. if (currentFragment == fragment)  
10. return;  
11.   
12. if (!fragment.isAdded()) { // 如果当前fragment未被添加,则添加到Fragment管理器中  
13.             transaction.hide(currentFragment)  
14.                     .add(R.id.content_layout, fragment).commit();  
15. else {  
16.             transaction.hide(currentFragment).show(fragment).commit();  
17.         }  
18.   
19.         currentFragment = fragment;  
20.     }


完整代码如下:

/BottomTabDemo/src/com/xiaowu/bottomtab/demo/MainActivity.java

[java]  view plain  copy

1. package com.xiaowu.bottomtab.demo;  
2.   
3.   
4.   
5. import android.os.Bundle;  
6. import android.support.v4.app.Fragment;  
7. import android.support.v4.app.FragmentActivity;  
8. import android.support.v4.app.FragmentTransaction;  
9. import android.view.View;  
10. import android.view.View.OnClickListener;  
11. import android.widget.ImageView;  
12. import android.widget.RelativeLayout;  
13. import android.widget.TextView;  
14.   
15. /**
16.  * 主Activity
17.  * 
18.  * @author wwj_748
19.  * 
20.  */  
21. public class MainActivity extends FragmentActivity implements OnClickListener {  
22.   
23. // 三个tab布局  
24. private RelativeLayout knowLayout, iWantKnowLayout, meLayout;  
25.   
26. // 底部标签切换的Fragment  
27. private Fragment knowFragment, iWantKnowFragment, meFragment,  
28.             currentFragment;  
29. // 底部标签图片  
30. private ImageView knowImg, iWantKnowImg, meImg;  
31. // 底部标签的文本  
32. private TextView knowTv, iWantKnowTv, meTv;  
33.   
34. @Override  
35. protected void onCreate(Bundle savedInstanceState) {  
36. super.onCreate(savedInstanceState);  
37.         setContentView(R.layout.activity_main);  
38.   
39.         initUI();  
40.         initTab();  
41.     }  
42.   
43. /**
44.      * 初始化UI
45.      */  
46. private void initUI() {  
47.         knowLayout = (RelativeLayout) findViewById(R.id.rl_know);  
48.         iWantKnowLayout = (RelativeLayout) findViewById(R.id.rl_want_know);  
49.         meLayout = (RelativeLayout) findViewById(R.id.rl_me);  
50. this);  
51. this);  
52. this);  
53.   
54.         knowImg = (ImageView) findViewById(R.id.iv_know);  
55.         iWantKnowImg = (ImageView) findViewById(R.id.iv_i_want_know);  
56.         meImg = (ImageView) findViewById(R.id.iv_me);  
57.         knowTv = (TextView) findViewById(R.id.tv_know);  
58.         iWantKnowTv = (TextView) findViewById(R.id.tv_i_want_know);  
59.         meTv = (TextView) findViewById(R.id.tv_me);  
60.   
61.     }  
62.   
63. /**
64.      * 初始化底部标签
65.      */  
66. private void initTab() {  
67. if (knowFragment == null) {  
68. new ZhidaoFragment();  
69.         }  
70.   
71. if (!knowFragment.isAdded()) {  
72. // 提交事务  
73.             getSupportFragmentManager().beginTransaction()  
74.                     .add(R.id.content_layout, knowFragment).commit();  
75.   
76. // 记录当前Fragment  
77.             currentFragment = knowFragment;  
78. // 设置图片文本的变化  
79.             knowImg.setImageResource(R.drawable.btn_know_pre);  
80.             knowTv.setTextColor(getResources()  
81.                     .getColor(R.color.bottomtab_press));  
82.             iWantKnowImg.setImageResource(R.drawable.btn_wantknow_nor);  
83.             iWantKnowTv.setTextColor(getResources().getColor(  
84.                     R.color.bottomtab_normal));  
85.             meImg.setImageResource(R.drawable.btn_my_nor);  
86.             meTv.setTextColor(getResources().getColor(R.color.bottomtab_normal));  
87.   
88.         }  
89.   
90.     }  
91.   
92. @Override  
93. public void onClick(View view) {  
94. switch (view.getId()) {  
95. case R.id.rl_know: // 知道  
96.             clickTab1Layout();  
97. break;  
98. case R.id.rl_want_know: // 我想知道  
99.             clickTab2Layout();  
100. break;  
101. case R.id.rl_me: // 我的  
102.             clickTab3Layout();  
103. break;  
104. default:  
105. break;  
106.         }  
107.     }  
108.   
109. /**
110.      * 点击第一个tab
111.      */  
112. private void clickTab1Layout() {  
113. if (knowFragment == null) {  
114. new ZhidaoFragment();  
115.         }  
116.         addOrShowFragment(getSupportFragmentManager().beginTransaction(), knowFragment);  
117.           
118. // 设置底部tab变化  
119.         knowImg.setImageResource(R.drawable.btn_know_pre);  
120.         knowTv.setTextColor(getResources().getColor(R.color.bottomtab_press));  
121.         iWantKnowImg.setImageResource(R.drawable.btn_wantknow_nor);  
122.         iWantKnowTv.setTextColor(getResources().getColor(  
123.                 R.color.bottomtab_normal));  
124.         meImg.setImageResource(R.drawable.btn_my_nor);  
125.         meTv.setTextColor(getResources().getColor(R.color.bottomtab_normal));  
126.     }  
127.   
128. /**
129.      * 点击第二个tab
130.      */  
131. private void clickTab2Layout() {  
132. if (iWantKnowFragment == null) {  
133. new IWantKnowFragment();  
134.         }  
135.         addOrShowFragment(getSupportFragmentManager().beginTransaction(), iWantKnowFragment);  
136.           
137.         knowImg.setImageResource(R.drawable.btn_know_nor);  
138.         knowTv.setTextColor(getResources().getColor(R.color.bottomtab_normal));  
139.         iWantKnowImg.setImageResource(R.drawable.btn_wantknow_pre);  
140.         iWantKnowTv.setTextColor(getResources().getColor(  
141.                 R.color.bottomtab_press));  
142.         meImg.setImageResource(R.drawable.btn_my_nor);  
143.         meTv.setTextColor(getResources().getColor(R.color.bottomtab_normal));  
144.   
145.     }  
146.   
147. /**
148.      * 点击第三个tab
149.      */  
150. private void clickTab3Layout() {  
151. if (meFragment == null) {  
152. new MeFragment();  
153.         }  
154.           
155.         addOrShowFragment(getSupportFragmentManager().beginTransaction(), meFragment);  
156.         knowImg.setImageResource(R.drawable.btn_know_nor);  
157.         knowTv.setTextColor(getResources().getColor(R.color.bottomtab_normal));  
158.         iWantKnowImg.setImageResource(R.drawable.btn_wantknow_nor);  
159.         iWantKnowTv.setTextColor(getResources().getColor(  
160.                 R.color.bottomtab_normal));  
161.         meImg.setImageResource(R.drawable.btn_my_pre);  
162.         meTv.setTextColor(getResources().getColor(R.color.bottomtab_press));  
163.           
164.     }  
165.   
166. /**
167.      * 添加或者显示碎片
168.      * 
169.      * @param transaction
170.      * @param fragment
171.      */  
172. private void addOrShowFragment(FragmentTransaction transaction,  
173.             Fragment fragment) {  
174. if (currentFragment == fragment)  
175. return;  
176.   
177. if (!fragment.isAdded()) { // 如果当前fragment未被添加,则添加到Fragment管理器中  
178.             transaction.hide(currentFragment)  
179.                     .add(R.id.content_layout, fragment).commit();  
180. else {  
181.             transaction.hide(currentFragment).show(fragment).commit();  
182.         }  
183.   
184.         currentFragment = fragment;  
185.     }  
186.   
187. }