一般使用過ucweb-android版的人都應該對其特殊的menu有一定的印象,把menu做成tab-menu(支持分頁的menu),可以容納比android傳統的menu更豐富的內容(android的menu超過6項則縮略在[更多]里),本文參考網上的例子的基礎上對例子進行簡化以及封裝,使其作為一個復合控件融入自己的framework。
先來看看本文程序運行的效果如下圖所示:
tabmenu本身就是一個popupwindow,popupwindow上面放了兩個gridview,第一個gridview就是分頁標簽,位于popupwindow的頂部,第二個gridview是菜單,位于popupwindow的主體。為了實現popupwindow的彈出/退出的動畫效果,本文使用了以下代碼:
在工程的res文件夾里添加anim子目錄,再新建文件popup_enter.xml:
1
2
3
4
5
|
<?xml version= "1.0" encoding= "utf-8" ?> <set xmlns:android= "http://schemas.android.com/apk/res/android" > <translate android:fromydelta= "100%p" android:toydelta= "0" android:duration= "1000" /> <alpha android:fromalpha= "0.0" android:toalpha= "1.0" android:duration= "1000" /> </set> |
新建文件popup_exit.xml:
1
2
3
4
5
|
<?xml version= "1.0" encoding= "utf-8" ?> <set xmlns:android= "http://schemas.android.com/apk/res/android" > <translate android:fromydelta= "0" android:toydelta= "100%p" android:duration= "1000" /> <alpha android:fromalpha= "1.0" android:toalpha= "0.0" android:duration= "1000" /> </set> |
在工程的values文件夾里新建文件popup_animation.xml:
1
2
3
4
5
6
7
|
<?xml version= "1.0" encoding= "utf-8" ?> <resources> <style name= "popupanimation" parent= "android:animation" > <item name= "android:windowenteranimation" > @anim /popup_enter</item> <item name= "android:windowexitanimation" > @anim /popup_exit</item> </style> </resources> |
main.xml的源碼如下:
1
2
3
4
5
6
7
|
<?xml version= "1.0" encoding= "utf-8" ?> <linearlayout android:id= "@+id/linearlayout01" android:layout_width= "fill_parent" android:layout_height= "fill_parent" xmlns:android= "http://schemas.android.com/apk/res/android" > <textview android:id= "@+id/textview01" android:layout_height= "wrap_content" android:layout_width= "fill_parent" android:text= "擴展menu----hellogv" ></textview> </linearlayout> |
tabmenu的封裝類tabmenu.java的源碼如下:
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
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
|
package com.testtabmenu; import android.content.context; import android.graphics.color; import android.graphics.drawable.colordrawable; import android.view.gravity; import android.view.view; import android.view.viewgroup; import android.widget.baseadapter; import android.widget.gridview; import android.widget.imageview; import android.widget.linearlayout; import android.widget.popupwindow; import android.widget.textview; import android.widget.adapterview.onitemclicklistener; import android.widget.linearlayout.layoutparams; public class tabmenu extends popupwindow{ private gridview gvbody, gvtitle; private linearlayout mlayout; private menutitleadapter titleadapter; public tabmenu(context context,onitemclicklistener titleclick,onitemclicklistener bodyclick, menutitleadapter titleadapter, int colorbgtabmenu, int anitabmenu){ super (context); mlayout = new linearlayout(context); mlayout.setorientation(linearlayout.vertical); //標題選項欄 gvtitle = new gridview(context); gvtitle.setlayoutparams( new layoutparams(layoutparams.fill_parent, layoutparams.wrap_content)); gvtitle.setnumcolumns(titleadapter.getcount()); gvtitle.setstretchmode(gridview.stretch_column_width); gvtitle.setverticalspacing( 1 ); gvtitle.sethorizontalspacing( 1 ); gvtitle.setgravity(gravity.center); gvtitle.setonitemclicklistener(titleclick); gvtitle.setadapter(titleadapter); gvtitle.setselector( new colordrawable(color.transparent)); //選中的時候為透明色 this .titleadapter=titleadapter; //子選項欄 gvbody = new gridview(context); gvbody.setlayoutparams( new layoutparams(layoutparams.fill_parent,layoutparams.wrap_content)); gvbody.setselector( new colordrawable(color.transparent)); //選中的時候為透明色 gvbody.setnumcolumns( 4 ); gvbody.setstretchmode(gridview.stretch_column_width); gvbody.setverticalspacing( 10 ); gvbody.sethorizontalspacing( 10 ); gvbody.setpadding( 10 , 10 , 10 , 10 ); gvbody.setgravity(gravity.center); gvbody.setonitemclicklistener(bodyclick); mlayout.addview(gvtitle); mlayout.addview(gvbody); //設置默認項 this .setcontentview(mlayout); this .setwidth(layoutparams.fill_parent); this .setheight(layoutparams.wrap_content); this .setbackgrounddrawable( new colordrawable(colorbgtabmenu)); // 設置tabmenu菜單背景 this .setanimationstyle(anitabmenu); this .setfocusable( true ); // menu菜單獲得焦點 如果沒有獲得焦點menu菜單中的控件事件無法響應 } public void settitleselect( int index) { gvtitle.setselection(index); this .titleadapter.setfocus(index); } public void setbodyselect( int index, int colorselbody) { int count=gvbody.getchildcount(); for ( int i= 0 ;i<count;i++) { if (i!=index) ((linearlayout)gvbody.getchildat(i)).setbackgroundcolor(color.transparent); } ((linearlayout)gvbody.getchildat(index)).setbackgroundcolor(colorselbody); } public void setbodyadapter(menubodyadapter bodyadapter) { gvbody.setadapter(bodyadapter); } /** * 自定義adapter,tabmenu的每個分頁的主體 * */ static public class menubodyadapter extends baseadapter { private context mcontext; private int fontcolor,fontsize; private string[] texts; private int [] resid; /** * 設置tabmenu的分頁主體 * @param context 調用方的上下文 * @param texts 按鈕集合的字符串數組 * @param resid 按鈕集合的圖標資源數組 * @param fontsize 按鈕字體大小 * @param color 按鈕字體顏色 */ public menubodyadapter(context context, string[] texts, int [] resid, int fontsize, int fontcolor) { this .mcontext = context; this .fontcolor = fontcolor; this .texts = texts; this .fontsize=fontsize; this .resid=resid; } public int getcount() { return texts.length; } public object getitem( int position) { return makemenybody(position); } public long getitemid( int position) { return position; } private linearlayout makemenybody( int position) { linearlayout result= new linearlayout( this .mcontext); result.setorientation(linearlayout.vertical); result.setgravity(gravity.center_horizontal|gravity.center_vertical); result.setpadding( 10 , 10 , 10 , 10 ); textview text = new textview( this .mcontext); text.settext(texts[position]); text.settextsize(fontsize); text.settextcolor(fontcolor); text.setgravity(gravity.center); text.setpadding( 5 , 5 , 5 , 5 ); imageview img= new imageview( this .mcontext); img.setbackgroundresource(resid[position]); result.addview(img, new linearlayout.layoutparams( new layoutparams(layoutparams.wrap_content,layoutparams.wrap_content))); result.addview(text); return result; } public view getview( int position, view convertview, viewgroup parent) { return makemenybody(position); } } /** * 自定義adapter,tabmenu的分頁標簽部分 * */ static public class menutitleadapter extends baseadapter { private context mcontext; private int fontcolor,unselcolor,selcolor; private textview[] title; /** * 設置tabmenu的title * @param context 調用方的上下文 * @param titles 分頁標簽的字符串數組 * @param fontsize 字體大小 * @param fontcolor 字體顏色 * @param unselcolor 未選中項的背景色 * @param selcolor 選中項的背景色 */ public menutitleadapter(context context, string[] titles, int fontsize, int fontcolor, int unselcolor, int selcolor) { this .mcontext = context; this .fontcolor = fontcolor; this .unselcolor = unselcolor; this .selcolor=selcolor; this .title = new textview[titles.length]; for ( int i = 0 ; i < titles.length; i++) { title[i] = new textview(mcontext); title[i].settext(titles[i]); title[i].settextsize(fontsize); title[i].settextcolor(fontcolor); title[i].setgravity(gravity.center); title[i].setpadding( 10 , 10 , 10 , 10 ); } } public int getcount() { return title.length; } public object getitem( int position) { return title[position]; } public long getitemid( int position) { return title[position].getid(); } /** * 設置選中的效果 */ private void setfocus( int index) { for ( int i= 0 ;i<title.length;i++) { if (i!=index) { title[i].setbackgrounddrawable( new colordrawable(unselcolor)); //設置沒選中的顏色 title[i].settextcolor(fontcolor); //設置沒選中項的字體顏色 } } title[index].setbackgroundcolor( 0x00 ); //設置選中項的顏色 title[index].settextcolor(selcolor); //設置選中項的字體顏色 } public view getview( int position, view convertview, viewgroup parent) { view v; if (convertview == null ) { v = title[position]; } else { v = convertview; } return v; } } } |
testtabmenu介紹了數據的定義以及tabmenu的使用,源碼如下:
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
|
package com.testtabmenu; import android.app.activity; import android.graphics.color; import android.os.bundle; import android.view.gravity; import android.view.menu; import android.view.view; import android.widget.adapterview; import android.widget.adapterview.onitemclicklistener; import android.widget.toast; public class testtabmenu extends activity { tabmenu.menubodyadapter []bodyadapter= new tabmenu.menubodyadapter[ 3 ]; tabmenu.menutitleadapter titleadapter; tabmenu tabmenu; int seltitle= 0 ; @override public void oncreate(bundle savedinstancestate) { super .oncreate(savedinstancestate); setcontentview(r.layout.main); //設置分頁欄的標題 titleadapter = new tabmenu.menutitleadapter( this , new string[] { "常用" , "設置" , "工具" }, 16 , 0xff222222 ,color.ltgray,color.white); //定義每項分頁欄的內容 bodyadapter[ 0 ]= new tabmenu.menubodyadapter( this , new string[] { "常用1" , "常用2" , }, new int [] { r.drawable.menu_test, r.drawable.menu_bookmark}, 13 , 0xffffffff ); bodyadapter[ 1 ]= new tabmenu.menubodyadapter( this , new string[] { "設置1" , "設置2" , "設置3" }, new int [] { r.drawable.menu_edit, r.drawable.menu_delete, r.drawable.menu_fullscreen}, 13 , 0xffffffff ); bodyadapter[ 2 ]= new tabmenu.menubodyadapter( this , new string[] { "工具1" , "工具2" , "工具3" , "工具4" }, new int [] { r.drawable.menu_copy, r.drawable.menu_cut, r.drawable.menu_normalmode, r.drawable.menu_quit }, 13 , 0xffffffff ); tabmenu= new tabmenu( this , new titleclickevent(), new bodyclickevent(), titleadapter, 0x55123456 , //tabmenu的背景顏色 r.style.popupanimation); //出現與消失的動畫 tabmenu.update(); tabmenu.settitleselect( 0 ); tabmenu.setbodyadapter(bodyadapter[ 0 ]); } class titleclickevent implements onitemclicklistener{ @override public void onitemclick(adapterview<?> arg0, view arg1, int arg2, long arg3) { seltitle=arg2; tabmenu.settitleselect(arg2); tabmenu.setbodyadapter(bodyadapter[arg2]); } } class bodyclickevent implements onitemclicklistener{ @override public void onitemclick(adapterview<?> arg0, view arg1, int arg2, long arg3) { tabmenu.setbodyselect(arg2,color.gray); string str= "第" +string.valueof(seltitle)+ "欄/n/r" + "第" +string.valueof(arg2)+ "項" ; toast.maketext(testtabmenu. this , str, 500 ).show(); } } @override /** * 創建menu */ public boolean oncreateoptionsmenu(menu menu) { menu.add( "menu" ); // 必須創建一項 return super .oncreateoptionsmenu(menu); } @override /** * 攔截menu */ public boolean onmenuopened( int featureid, menu menu) { if (tabmenu != null ) { if (tabmenu.isshowing()) tabmenu.dismiss(); else { tabmenu.showatlocation(findviewbyid(r.id.linearlayout01), gravity.bottom, 0 , 0 ); } } return false ; // 返回為true 則顯示系統menu } } |
感興趣的讀者可以自己動手測試一下本文所述實例,相信會對大家的android程序開發有一定幫助。