前言
本篇博客要分享的一个UI效果——实现底部切换标签,想必大家在一些应用上面遇到过这种效果了,最典型的就是微信了,可以左右滑动切换页面,也可以点击标签页滑动页面,它们是如何实现的呢,本篇博客为了简单只介绍如何实现点击底部切换标签页。
先来看看我们想实现的效果图:
这样的页面实现起来其实很简单的,首先我们从布局入手:
分为三部分
第一部分:顶部导航栏布局
第二部分:中部显示内容布局
第三部分:底部标签布局
/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. }