一般使用過(guò)ucweb-android版的人都應(yīng)該對(duì)其特殊的menu有一定的印象,把menu做成tab-menu(支持分頁(yè)的menu),可以容納比android傳統(tǒng)的menu更豐富的內(nèi)容(android的menu超過(guò)6項(xiàng)則縮略在[更多]里),本文參考網(wǎng)上的例子的基礎(chǔ)上對(duì)例子進(jìn)行簡(jiǎn)化以及封裝,使其作為一個(gè)復(fù)合控件融入自己的framework。
先來(lái)看看本文程序運(yùn)行的效果如下圖所示:
tabmenu本身就是一個(gè)popupwindow,popupwindow上面放了兩個(gè)gridview,第一個(gè)gridview就是分頁(yè)標(biāo)簽,位于popupwindow的頂部,第二個(gè)gridview是菜單,位于popupwindow的主體。為了實(shí)現(xiàn)popupwindow的彈出/退出的動(dòng)畫(huà)效果,本文使用了以下代碼:
在工程的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= "擴(kuò)展menu----hellogv" ></textview> </linearlayout> |
tabmenu的封裝類(lèi)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); //標(biāo)題選項(xiàng)欄 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)); //選中的時(shí)候?yàn)橥该魃?/code> this .titleadapter=titleadapter; //子選項(xiàng)欄 gvbody = new gridview(context); gvbody.setlayoutparams( new layoutparams(layoutparams.fill_parent,layoutparams.wrap_content)); gvbody.setselector( new colordrawable(color.transparent)); //選中的時(shí)候?yàn)橥该魃?/code> 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); //設(shè)置默認(rèn)項(xiàng) this .setcontentview(mlayout); this .setwidth(layoutparams.fill_parent); this .setheight(layoutparams.wrap_content); this .setbackgrounddrawable( new colordrawable(colorbgtabmenu)); // 設(shè)置tabmenu菜單背景 this .setanimationstyle(anitabmenu); this .setfocusable( true ); // menu菜單獲得焦點(diǎn) 如果沒(méi)有獲得焦點(diǎn)menu菜單中的控件事件無(wú)法響應(yīng) } 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的每個(gè)分頁(yè)的主體 * */ static public class menubodyadapter extends baseadapter { private context mcontext; private int fontcolor,fontsize; private string[] texts; private int [] resid; /** * 設(shè)置tabmenu的分頁(yè)主體 * @param context 調(diào)用方的上下文 * @param texts 按鈕集合的字符串?dāng)?shù)組 * @param resid 按鈕集合的圖標(biāo)資源數(shù)組 * @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的分頁(yè)標(biāo)簽部分 * */ static public class menutitleadapter extends baseadapter { private context mcontext; private int fontcolor,unselcolor,selcolor; private textview[] title; /** * 設(shè)置tabmenu的title * @param context 調(diào)用方的上下文 * @param titles 分頁(yè)標(biāo)簽的字符串?dāng)?shù)組 * @param fontsize 字體大小 * @param fontcolor 字體顏色 * @param unselcolor 未選中項(xiàng)的背景色 * @param selcolor 選中項(xiàng)的背景色 */ 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(); } /** * 設(shè)置選中的效果 */ private void setfocus( int index) { for ( int i= 0 ;i<title.length;i++) { if (i!=index) { title[i].setbackgrounddrawable( new colordrawable(unselcolor)); //設(shè)置沒(méi)選中的顏色 title[i].settextcolor(fontcolor); //設(shè)置沒(méi)選中項(xiàng)的字體顏色 } } title[index].setbackgroundcolor( 0x00 ); //設(shè)置選中項(xiàng)的顏色 title[index].settextcolor(selcolor); //設(shè)置選中項(xiàng)的字體顏色 } public view getview( int position, view convertview, viewgroup parent) { view v; if (convertview == null ) { v = title[position]; } else { v = convertview; } return v; } } } |
testtabmenu介紹了數(shù)據(jù)的定義以及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); //設(shè)置分頁(yè)欄的標(biāo)題 titleadapter = new tabmenu.menutitleadapter( this , new string[] { "常用" , "設(shè)置" , "工具" }, 16 , 0xff222222 ,color.ltgray,color.white); //定義每項(xiàng)分頁(yè)欄的內(nèi)容 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[] { "設(shè)置1" , "設(shè)置2" , "設(shè)置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); //出現(xiàn)與消失的動(dòng)畫(huà) 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)+ "項(xiàng)" ; toast.maketext(testtabmenu. this , str, 500 ).show(); } } @override /** * 創(chuàng)建menu */ public boolean oncreateoptionsmenu(menu menu) { menu.add( "menu" ); // 必須創(chuàng)建一項(xiàng) 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 則顯示系統(tǒng)menu } } |
感興趣的讀者可以自己動(dòng)手測(cè)試一下本文所述實(shí)例,相信會(huì)對(duì)大家的android程序開(kāi)發(fā)有一定幫助。