Android底部导航栏的四种实现
现在大多数App都会用到底部导航栏,比如常见的聊天工具QQ、微信,购物App等等,有了底部导航栏,用户可以随时切换界面,查看不同的内容。它的实现方式也很多,以前大多使用TabHost来实现,但是现在我们有很多更好的选择。
使用LinearLayout + TextView实现了底部导航栏的效果
首先看看工程目录:
Step 1:实现底部选项的一些资源文件
图片Drawable资源:tab_menu_deal.xml
1
2
3
4
5
不用做过多解释了吧,点击图片,变换图片。
其他三个依葫芦画瓢。
文字资源:tab_menu_deal_text.xml
1
2
3
4
5
6
7
背景资源 tab_menu_bg.xml:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Step 2:编写我们的Activity布局
activity_main.xml:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
效果图如下:
Step 3:创建一个Fragment的简单布局与类:
first_fragment.xml:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
FirstFragment.java:
publicclassFirstFragmentextendsFragment{privateString context;privateTextView mTextView;publicFirstFragment(String context){this.context = context; }@[email protected](LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.first_fragment,container,false); mTextView = (TextView)view.findViewById(R.id.txt_content);//mTextView = (TextView)getActivity().findViewById(R.id.txt_content);mTextView.setText(context);returnview; }}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Step 4:编写MainActivity.java
publicclassMainActivityextendsAppCompatActivityimplementsView.OnClickListener{privateTextView topBar;privateTextView tabDeal;privateTextView tabPoi;privateTextView tabMore;privateTextView tabUser;privateFrameLayout ly_content;privateFirstFragment f1,f2,f3,f4;privateFragmentManager fragmentManager;@OverrideprotectedvoidonCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_main); bindView(); }//UI组件初始化与事件绑定privatevoidbindView() { topBar = (TextView)this.findViewById(R.id.txt_top); tabDeal = (TextView)this.findViewById(R.id.txt_deal); tabPoi = (TextView)this.findViewById(R.id.txt_poi); tabUser = (TextView)this.findViewById(R.id.txt_user); tabMore = (TextView)this.findViewById(R.id.txt_more); ly_content = (FrameLayout) findViewById(R.id.fragment_container); tabDeal.setOnClickListener(this); tabMore.setOnClickListener(this); tabUser.setOnClickListener(this); tabPoi.setOnClickListener(this); }//重置所有文本的选中状态publicvoidselected(){ tabDeal.setSelected(false); tabMore.setSelected(false); tabPoi.setSelected(false); tabUser.setSelected(false); }//隐藏所有FragmentpublicvoidhideAllFragment(FragmentTransaction transaction){if(f1!=null){ transaction.hide(f1); }if(f2!=null){ transaction.hide(f2); }if(f3!=null){ transaction.hide(f3); }if(f4!=null){ transaction.hide(f4); } }@OverridepublicvoidonClick(View v) { FragmentTransaction transaction = getFragmentManager().beginTransaction(); hideAllFragment(transaction);switch(v.getId()){caseR.id.txt_deal: selected(); tabDeal.setSelected(true);if(f1==null){ f1 =newFirstFragment("第一个Fragment"); transaction.add(R.id.fragment_container,f1); }else{ transaction.show(f1); }break;caseR.id.txt_more: selected(); tabMore.setSelected(true);if(f2==null){ f2 =newFirstFragment("第二个Fragment"); transaction.add(R.id.fragment_container,f2); }else{ transaction.show(f2); }break;caseR.id.txt_poi: selected(); tabPoi.setSelected(true);if(f3==null){ f3 =newFirstFragment("第三个Fragment"); transaction.add(R.id.fragment_container,f3); }else{ transaction.show(f3); }break;caseR.id.txt_user: selected(); tabUser.setSelected(true);if(f4==null){ f4 =newFirstFragment("第四个Fragment"); transaction.add(R.id.fragment_container,f4); }else{ transaction.show(f4); }break; } transaction.commit(); }}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
实现效果图如下:
使用RadioGroup + RadioButton实现了底部导航栏的效果
这一次的资源文件和上一次是一样的,只需要把外drawable类的资源的selected 状态修改成checked状态:
1
2
3
4
5
6
7
其他文字资源及背景资源不变
这里我们首先从主布局文件开始:
Step 2:编写我们的Activity布局
由于布局中的RadioButton的属性大部分是一样的,因此我们可以将这一部分一样的代码抽取出来,写到style.xml文件中:
style.xml:
@color/colorPrimary @color/colorPrimaryDark @color/colorAccent 0dp 1 match_parent @drawable/tab_menu_bg @null center 3dp @drawable/tab_menu_text 18sp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
然后我们的activity_main.xml中的RadioButton就用不着次次都写相同的代码了, 只需让RadioButton的style=”@style/tab_menu_item”就可以了!
activity_main.xml :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
效果图如下:
Step 3:创建一个Fragment的简单布局与类:
my_fragment.xml :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
MyFragment.java :
publicclassMyFragmentextendsFragment{privateString context;privateTextView mTextView;publicMyFragment(String context){this.context = context; }@[email protected](LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.my_fragment,container,false); mTextView = (TextView)view.findViewById(R.id.textView); mTextView.setText(context);returnview; }}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Step 4:编写MainActivity.java
publicclassMainActivityextendsAppCompatActivityimplementsRadioGroup.OnCheckedChangeListener{privateRadioGroup rpTab;privateRadioButton rbDeal,rbPoi,rbMore,rbUser;privateMyFragment fg1,fg2,fg3,fg4;@OverrideprotectedvoidonCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); bindView(); }privatevoidbindView() { rpTab = (RadioGroup)findViewById(R.id.rd_group); rpTab.setOnCheckedChangeListener(this); rbDeal = (RadioButton)findViewById(R.id.rd_menu_deal); rbPoi = (RadioButton)findViewById(R.id.rd_menu_poi); rbMore = (RadioButton)findViewById(R.id.rd_menu_more); rbUser = (RadioButton)findViewById(R.id.rd_menu_user); rbDeal.setChecked(true); }publicvoidhideAllFragment(FragmentTransaction transaction){if(fg1!=null){ transaction.hide(fg1); }if(fg2!=null){ transaction.hide(fg2); }if(fg3!=null){ transaction.hide(fg3); }if(fg4!=null){ transaction.hide(fg4); } }@OverridepublicvoidonCheckedChanged(RadioGroup group,intcheckedId) { FragmentTransaction transaction = getFragmentManager().beginTransaction(); hideAllFragment(transaction);switch(checkedId){caseR.id.rd_menu_deal:if(fg1==null){ fg1 =newMyFragment("第一个Fragment"); transaction.add(R.id.fragment_container,fg1); }else{ transaction.show(fg1); }break;caseR.id.rd_menu_poi:if(fg2==null){ fg2 =newMyFragment("第二个Fragment"); transaction.add(R.id.fragment_container,fg2); }else{ transaction.show(fg2); }break;caseR.id.rd_menu_more:if(fg3==null){ fg3 =newMyFragment("第三个Fragment"); transaction.add(R.id.fragment_container,fg3); }else{ transaction.show(fg3); }break;caseR.id.rd_menu_user:if(fg4==null){ fg4 =newMyFragment("第四个Fragment"); transaction.add(R.id.fragment_container,fg4); }else{ transaction.show(fg4); }break; } transaction.commit(); }}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
效果图和上面一样:
前面我们已经跟大家讲解了实现底部导航栏的两种方案,但是这两种方案只适合普通的情况,如果 是像新浪微博那样的,想在底部导航栏上的item带有一个红色的小点,然后加上一个消息数目这样, 前面两种方案就显得无力了,我们来看看别人的APP是怎么做的,打开手机的开发者选项,勾选里面的: 显示布局边界,然后打开我们参考的那个App,可以看到底部导航栏是这样的:
上面这个图我们就可以看出,这种底部导航栏不是简单的TextView或者RadioGroup构成的, 大概布局方案可能是:外层一个LinearLayout,中间一个RelativeLayout,而在中间有一个TextView, 然后再在TextView的右上角有一个红色圆圈背景的TextView或者一个红色的小点; 大概就这样,而这些小点平时的时候应该设置的不可见,当收到信息推送,即有相关类别信息的 时候再可见,并且显示对应的信息数目!那么下面我们就来实现下这种底部导航栏的效果,!
实现效果:
为了方便理解,这里通过点击按钮的形式,模拟收到推送信息,然后显示红色点!
Step 1:相关资源文件的准备:
和前面一样,准备好drawable系列的资源:
文字资源:tab_menu_text.xml
1
2
3
4
5
6
图标资源:tab_menu_better.xml
1
2
3
4
5
6
其他三个依葫芦画瓢!
Step 2:编写activity的布局代码:
因为四个选项的TextView以及右上角的红点数字属性都差不多,如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
我们将他们抽取出来,写到style.xml里:
5dp wrap_content 48dp true @drawable/tab_menu_text 20dp 20dp @mipmap/bg_num -10dp 12sp center @color/text_white
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
然后开始编写我们的activity.xml布局:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
效果图如下:
Step 3:编写Fragment界面布局以及类
Fragment布局由四个普通按钮构成:
fragment_my.xml:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
接着是自定义的Fragment类,这里的话我们通过getActivity.findViewById()来获得Activity 中的小红点,这里仅仅是简单的控制显示而已!
MyFragment.java:
publicclassMyFragmentextendsFragmentimplementsView.OnClickListener{privateContext mContext;privateButton btn_one;privateButton btn_two;privateButton btn_three;privateButton btn_four;@[email protected](LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.frament_my,container,false); btn_one = (Button)view.findViewById(R.id.btn_one); btn_two = (Button)view.findViewById(R.id.btn_two); btn_three = (Button)view.findViewById(R.id.btn_three); btn_four = (Button)view.findViewById(R.id.btn_four); btn_one.setOnClickListener(this); btn_two.setOnClickListener(this); btn_three.setOnClickListener(this); btn_four.setOnClickListener(this);returnview; }@OverridepublicvoidonClick(View v) {switch(v.getId()){caseR.id.btn_one: TextView mTextViewDeal = (TextView)getActivity().findViewById(R.id.tab_menu_deal_num); mTextViewDeal.setText("11"); mTextViewDeal.setVisibility(View.VISIBLE);break;caseR.id.btn_two: TextView mTextViewPoi = (TextView)getActivity().findViewById(R.id.tab_menu_poi_num); mTextViewPoi.setText("99"); mTextViewPoi.setVisibility(View.VISIBLE);break;caseR.id.btn_three: TextView mTextViewMore = (TextView)getActivity().findViewById(R.id.tab_menu_more_num); mTextViewMore.setText("999+"); mTextViewMore.setVisibility(View.VISIBLE);break;caseR.id.btn_four: ImageView mImageView = (ImageView) getActivity ().findViewById(R.id.tab_menu_setting_partner); mImageView.setVisibility(View.VISIBLE);break; } }}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
Step 4:编写MainActivity
我们在这里完成主要的逻辑实现,有些部分和前面TextView实现底部导航栏的效果类似, 就不具体讲解了,代码如下:
MainActivity.java:
publicclassMainActivityextendsAppCompatActivityimplementsView.OnClickListener{privateLinearLayout ly_one,ly_two,ly_three,ly_four;privateTextView mTextView1,mTextView2,mTextView3,mTextView4;privateTextView mTextNum1,mTextNum2,mTextNum3,mTxetNum3;privateImageView mImageView;@OverrideprotectedvoidonCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); bindView(); ly_one.performClick(); FragmentTransaction transaction = getFragmentManager().beginTransaction(); MyFragment fg1 =newMyFragment(); transaction.add(R.id.fragment_container,fg1); transaction.commit(); }privatevoidbindView() { ly_one = (LinearLayout)findViewById(R.id.ly_tab_menu_deal); ly_two = (LinearLayout)findViewById(R.id.ly_tab_menu_poi); ly_three = (LinearLayout)findViewById(R.id.ly_tab_menu_more); ly_four = (LinearLayout)findViewById(R.id.ly_tab_menu_user); mTextView1 = (TextView)findViewById(R.id.tab_menu_deal); mTextView2 = (TextView)findViewById(R.id.tab_menu_poi); mTextView3 = (TextView)findViewById(R.id.tab_menu_more); mTextView4 = (TextView)findViewById(R.id.tab_menu_user); mTextNum1 = (TextView)findViewById(R.id.tab_menu_deal_num); mTextNum2 = (TextView)findViewById(R.id.tab_menu_poi_num); mTextNum3 = (TextView)findViewById(R.id.tab_menu_more_num); mImageView = (ImageView)findViewById(R.id.tab_menu_setting_partner); ly_one.setOnClickListener(this); ly_two.setOnClickListener(this); ly_three.setOnClickListener(this); ly_four.setOnClickListener(this); }//重置所有文本的选中状态privatevoidsetSelected() { mTextView1.setSelected(false); mTextView2.setSelected(false); mTextView3.setSelected(false); mTextView4.setSelected(false); }@OverridepublicvoidonClick(View v) {switch(v.getId()) {caseR.id.ly_tab_menu_deal: setSelected(); mTextView1.setSelected(true); mTextNum1.setVisibility(View.INVISIBLE);break;caseR.id.ly_tab_menu_poi: setSelected(); mTextView2.setSelected(true); mTextNum2.setVisibility(View.INVISIBLE);break;caseR.id.ly_tab_menu_more: setSelected(); mTextView3.setSelected(true); mTextNum3.setVisibility(View.INVISIBLE);break;caseR.id.ly_tab_menu_user: setSelected(); mTextView4.setSelected(true); mImageView.setVisibility(View.INVISIBLE);break; } }}
代码实现效果图:
这篇博客讲得很清楚~
http://blog.****.net/u010046908/article/details/50962081
摘自:http://blog.****.net/jxq1994/article/details/52573506