`
445822357
  • 浏览: 740555 次
文章分类
社区版块
存档分类
最新评论

仿UCWEB菜单功能

 
阅读更多

本文来自http://blog.csdn.net/hellogv/,引用必须注明出处!

快要过年了,在这里先祝广大的技术宅兔年快乐!
用过UCWEB-Android版的人都应该对其特殊的menu有印象,把menu做成Tab-Menu(支持分页的Menu),可以容纳比Android传统的menu更丰富的内容(Android的menu超过6项则缩略在[更多]里),本文参考网上的例子(作者:CoffeeCole,email:longkefan@foxmail.com),对例子进行简化以及封装,使其作为一个复合控件融入自己的framework。

先来看看本文程序运行的效果:

TabMenu本身就是一个PopupWindow,PopupWindow上面放了两个GridView,第一个GridView就是分页标签,位于PopupWindow的顶部,第二个GridView是菜单,位于PopupWindow的主体。为了实现PopupWindow的弹出/退出的动画效果,本文使用了以下代码:

在工程的res文件夹里添加anim子目录,再新建文件popup_enter.xml:

  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <setxmlns:android="http://schemas.android.com/apk/res/android">
  3. <translateandroid:fromYDelta="100%p"android:toYDelta="0"android:duration="1000"/>
  4. <alphaandroid:fromAlpha="0.0"android:toAlpha="1.0"android:duration="1000"/>
  5. </set>

新建文件popup_exit.xml:

  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <setxmlns:android="http://schemas.android.com/apk/res/android">
  3. <translateandroid:fromYDelta="0"android:toYDelta="100%p"android:duration="1000"/>
  4. <alphaandroid:fromAlpha="1.0"android:toAlpha="0.0"android:duration="1000"/>
  5. </set>

在工程的values文件夹里新建文件popup_animation.xml:

<?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. <?xmlversion="1.0"encoding="utf-8"?>
  2. <LinearLayoutandroid:id="@+id/LinearLayout01"
  3. android:layout_width="fill_parent"android:layout_height="fill_parent"
  4. xmlns:android="http://schemas.android.com/apk/res/android">
  5. <TextViewandroid:id="@+id/TextView01"android:layout_height="wrap_content"
  6. android:layout_width="fill_parent"android:text="扩展Menu----hellogv"></TextView>
  7. </LinearLayout>

TabMenu的封装类TabMenu.java的源码如下:

  1. packagecom.testTabMenu;
  2. importandroid.content.Context;
  3. importandroid.graphics.Color;
  4. importandroid.graphics.drawable.ColorDrawable;
  5. importandroid.view.Gravity;
  6. importandroid.view.View;
  7. importandroid.view.ViewGroup;
  8. importandroid.widget.BaseAdapter;
  9. importandroid.widget.GridView;
  10. importandroid.widget.ImageView;
  11. importandroid.widget.LinearLayout;
  12. importandroid.widget.PopupWindow;
  13. importandroid.widget.TextView;
  14. importandroid.widget.AdapterView.OnItemClickListener;
  15. importandroid.widget.LinearLayout.LayoutParams;
  16. publicclassTabMenuextendsPopupWindow{
  17. privateGridViewgvBody,gvTitle;
  18. privateLinearLayoutmLayout;
  19. privateMenuTitleAdaptertitleAdapter;
  20. publicTabMenu(Contextcontext,OnItemClickListenertitleClick,OnItemClickListenerbodyClick,
  21. MenuTitleAdaptertitleAdapter,intcolorBgTabMenu,intaniTabMenu){
  22. super(context);
  23. mLayout=newLinearLayout(context);
  24. mLayout.setOrientation(LinearLayout.VERTICAL);
  25. //标题选项栏
  26. gvTitle=newGridView(context);
  27. gvTitle.setLayoutParams(newLayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT));
  28. gvTitle.setNumColumns(titleAdapter.getCount());
  29. gvTitle.setStretchMode(GridView.STRETCH_COLUMN_WIDTH);
  30. gvTitle.setVerticalSpacing(1);
  31. gvTitle.setHorizontalSpacing(1);
  32. gvTitle.setGravity(Gravity.CENTER);
  33. gvTitle.setOnItemClickListener(titleClick);
  34. gvTitle.setAdapter(titleAdapter);
  35. gvTitle.setSelector(newColorDrawable(Color.TRANSPARENT));//选中的时候为透明色
  36. this.titleAdapter=titleAdapter;
  37. //子选项栏
  38. gvBody=newGridView(context);
  39. gvBody.setLayoutParams(newLayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT));
  40. gvBody.setSelector(newColorDrawable(Color.TRANSPARENT));//选中的时候为透明色
  41. gvBody.setNumColumns(4);
  42. gvBody.setStretchMode(GridView.STRETCH_COLUMN_WIDTH);
  43. gvBody.setVerticalSpacing(10);
  44. gvBody.setHorizontalSpacing(10);
  45. gvBody.setPadding(10,10,10,10);
  46. gvBody.setGravity(Gravity.CENTER);
  47. gvBody.setOnItemClickListener(bodyClick);
  48. mLayout.addView(gvTitle);
  49. mLayout.addView(gvBody);
  50. //设置默认项
  51. this.setContentView(mLayout);
  52. this.setWidth(LayoutParams.FILL_PARENT);
  53. this.setHeight(LayoutParams.WRAP_CONTENT);
  54. this.setBackgroundDrawable(newColorDrawable(colorBgTabMenu));//设置TabMenu菜单背景
  55. this.setAnimationStyle(aniTabMenu);
  56. this.setFocusable(true);//menu菜单获得焦点如果没有获得焦点menu菜单中的控件事件无法响应
  57. }
  58. publicvoidSetTitleSelect(intindex)
  59. {
  60. gvTitle.setSelection(index);
  61. this.titleAdapter.SetFocus(index);
  62. }
  63. publicvoidSetBodySelect(intindex,intcolorSelBody)
  64. {
  65. intcount=gvBody.getChildCount();
  66. for(inti=0;i<count;i++)
  67. {
  68. if(i!=index)
  69. ((LinearLayout)gvBody.getChildAt(i)).setBackgroundColor(Color.TRANSPARENT);
  70. }
  71. ((LinearLayout)gvBody.getChildAt(index)).setBackgroundColor(colorSelBody);
  72. }
  73. publicvoidSetBodyAdapter(MenuBodyAdapterbodyAdapter)
  74. {
  75. gvBody.setAdapter(bodyAdapter);
  76. }
  77. /**
  78. *自定义Adapter,TabMenu的每个分页的主体
  79. *
  80. */
  81. staticpublicclassMenuBodyAdapterextendsBaseAdapter{
  82. privateContextmContext;
  83. privateintfontColor,fontSize;
  84. privateString[]texts;
  85. privateint[]resID;
  86. /**
  87. *设置TabMenu的分页主体
  88. *@paramcontext调用方的上下文
  89. *@paramtexts按钮集合的字符串数组
  90. *@paramresID按钮集合的图标资源数组
  91. *@paramfontSize按钮字体大小
  92. *@paramcolor按钮字体颜色
  93. */
  94. publicMenuBodyAdapter(Contextcontext,String[]texts,int[]resID,intfontSize,intfontColor)
  95. {
  96. this.mContext=context;
  97. this.fontColor=fontColor;
  98. this.texts=texts;
  99. this.fontSize=fontSize;
  100. this.resID=resID;
  101. }
  102. publicintgetCount(){
  103. returntexts.length;
  104. }
  105. publicObjectgetItem(intposition){
  106. returnmakeMenyBody(position);
  107. }
  108. publiclonggetItemId(intposition){
  109. returnposition;
  110. }
  111. privateLinearLayoutmakeMenyBody(intposition)
  112. {
  113. LinearLayoutresult=newLinearLayout(this.mContext);
  114. result.setOrientation(LinearLayout.VERTICAL);
  115. result.setGravity(Gravity.CENTER_HORIZONTAL|Gravity.CENTER_VERTICAL);
  116. result.setPadding(10,10,10,10);
  117. TextViewtext=newTextView(this.mContext);
  118. text.setText(texts[position]);
  119. text.setTextSize(fontSize);
  120. text.setTextColor(fontColor);
  121. text.setGravity(Gravity.CENTER);
  122. text.setPadding(5,5,5,5);
  123. ImageViewimg=newImageView(this.mContext);
  124. img.setBackgroundResource(resID[position]);
  125. result.addView(img,newLinearLayout.LayoutParams(newLayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT)));
  126. result.addView(text);
  127. returnresult;
  128. }
  129. publicViewgetView(intposition,ViewconvertView,ViewGroupparent){
  130. returnmakeMenyBody(position);
  131. }
  132. }
  133. /**
  134. *自定义Adapter,TabMenu的分页标签部分
  135. *
  136. */
  137. staticpublicclassMenuTitleAdapterextendsBaseAdapter{
  138. privateContextmContext;
  139. privateintfontColor,unselcolor,selcolor;
  140. privateTextView[]title;
  141. /**
  142. *设置TabMenu的title
  143. *@paramcontext调用方的上下文
  144. *@paramtitles分页标签的字符串数组
  145. *@paramfontSize字体大小
  146. *@paramfontcolor字体颜色
  147. *@paramunselcolor未选中项的背景色
  148. *@paramselcolor选中项的背景色
  149. */
  150. publicMenuTitleAdapter(Contextcontext,String[]titles,intfontSize,
  151. intfontcolor,intunselcolor,intselcolor){
  152. this.mContext=context;
  153. this.fontColor=fontcolor;
  154. this.unselcolor=unselcolor;
  155. this.selcolor=selcolor;
  156. this.title=newTextView[titles.length];
  157. for(inti=0;i<titles.length;i++){
  158. title[i]=newTextView(mContext);
  159. title[i].setText(titles[i]);
  160. title[i].setTextSize(fontSize);
  161. title[i].setTextColor(fontColor);
  162. title[i].setGravity(Gravity.CENTER);
  163. title[i].setPadding(10,10,10,10);
  164. }
  165. }
  166. publicintgetCount(){
  167. returntitle.length;
  168. }
  169. publicObjectgetItem(intposition){
  170. returntitle[position];
  171. }
  172. publiclonggetItemId(intposition){
  173. returntitle[position].getId();
  174. }
  175. /**
  176. *设置选中的效果
  177. */
  178. privatevoidSetFocus(intindex)
  179. {
  180. for(inti=0;i<title.length;i++)
  181. {
  182. if(i!=index)
  183. {
  184. title[i].setBackgroundDrawable(newColorDrawable(unselcolor));//设置没选中的颜色
  185. title[i].setTextColor(fontColor);//设置没选中项的字体颜色
  186. }
  187. }
  188. title[index].setBackgroundColor(0x00);//设置选中项的颜色
  189. title[index].setTextColor(selcolor);//设置选中项的字体颜色
  190. }
  191. publicViewgetView(intposition,ViewconvertView,ViewGroupparent){
  192. Viewv;
  193. if(convertView==null){
  194. v=title[position];
  195. }else{
  196. v=convertView;
  197. }
  198. returnv;
  199. }
  200. }
  201. }

testTabMenu介绍了数据的定义以及TabMenu的使用,源码如下:

  1. packagecom.testTabMenu;
  2. importandroid.app.Activity;
  3. importandroid.graphics.Color;
  4. importandroid.os.Bundle;
  5. importandroid.view.Gravity;
  6. importandroid.view.Menu;
  7. importandroid.view.View;
  8. importandroid.widget.AdapterView;
  9. importandroid.widget.AdapterView.OnItemClickListener;
  10. importandroid.widget.Toast;
  11. publicclasstestTabMenuextendsActivity{
  12. TabMenu.MenuBodyAdapter[]bodyAdapter=newTabMenu.MenuBodyAdapter[3];
  13. TabMenu.MenuTitleAdaptertitleAdapter;
  14. TabMenutabMenu;
  15. intselTitle=0;
  16. @Override
  17. publicvoidonCreate(BundlesavedInstanceState){
  18. super.onCreate(savedInstanceState);
  19. setContentView(R.layout.main);
  20. //设置分页栏的标题
  21. titleAdapter=newTabMenu.MenuTitleAdapter(this,newString[]{"常用",
  22. "设置","工具"},16,0xFF222222,Color.LTGRAY,Color.WHITE);
  23. //定义每项分页栏的内容
  24. bodyAdapter[0]=newTabMenu.MenuBodyAdapter(this,newString[]{"常用1","常用2",},
  25. newint[]{R.drawable.menu_test,
  26. R.drawable.menu_bookmark},13,0xFFFFFFFF);
  27. bodyAdapter[1]=newTabMenu.MenuBodyAdapter(this,newString[]{"设置1","设置2",
  28. "设置3"},newint[]{R.drawable.menu_edit,
  29. R.drawable.menu_delete,R.drawable.menu_fullscreen},13,0xFFFFFFFF);
  30. bodyAdapter[2]=newTabMenu.MenuBodyAdapter(this,newString[]{"工具1","工具2",
  31. "工具3","工具4"},newint[]{R.drawable.menu_copy,
  32. R.drawable.menu_cut,R.drawable.menu_normalmode,
  33. R.drawable.menu_quit},13,0xFFFFFFFF);
  34. tabMenu=newTabMenu(this,
  35. newTitleClickEvent(),
  36. newBodyClickEvent(),
  37. titleAdapter,
  38. 0x55123456,//TabMenu的背景颜色
  39. R.style.PopupAnimation);//出现与消失的动画
  40. tabMenu.update();
  41. tabMenu.SetTitleSelect(0);
  42. tabMenu.SetBodyAdapter(bodyAdapter[0]);
  43. }
  44. classTitleClickEventimplementsOnItemClickListener{
  45. @Override
  46. publicvoidonItemClick(AdapterView<?>arg0,Viewarg1,intarg2,
  47. longarg3){
  48. selTitle=arg2;
  49. tabMenu.SetTitleSelect(arg2);
  50. tabMenu.SetBodyAdapter(bodyAdapter[arg2]);
  51. }
  52. }
  53. classBodyClickEventimplementsOnItemClickListener{
  54. @Override
  55. publicvoidonItemClick(AdapterView<?>arg0,Viewarg1,intarg2,
  56. longarg3){
  57. tabMenu.SetBodySelect(arg2,Color.GRAY);
  58. Stringstr="第"+String.valueOf(selTitle)+"栏/n/r"
  59. +"第"+String.valueOf(arg2)+"项";
  60. Toast.makeText(testTabMenu.this,str,500).show();
  61. }
  62. }
  63. @Override
  64. /**
  65. *创建MENU
  66. */
  67. publicbooleanonCreateOptionsMenu(Menumenu){
  68. menu.add("menu");//必须创建一项
  69. returnsuper.onCreateOptionsMenu(menu);
  70. }
  71. @Override
  72. /**
  73. *拦截MENU
  74. */
  75. publicbooleanonMenuOpened(intfeatureId,Menumenu){
  76. if(tabMenu!=null){
  77. if(tabMenu.isShowing())
  78. tabMenu.dismiss();
  79. else{
  80. tabMenu.showAtLocation(findViewById(R.id.LinearLayout01),
  81. Gravity.BOTTOM,0,0);
  82. }
  83. }
  84. returnfalse;//返回为true则显示系统menu
  85. }
  86. }

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics