用过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:
<?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:
<?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:
<?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的源码如下:
<?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"></textview>  </linearlayout>


tabmenu的封装类tabmenu.java的源码如下:
package com.iaiai.activity;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;/** *  * <p> * title: tabmenu.java * </p> * <p> * e-mail: 176291935@qq.com * </p> * <p> * qq: 176291935 * </p> * <p> * http: iaiai.iteye.com * </p> * <p> * create time: 2011-8-17 * </p> *  * @author 丸子 * @version 0.0.1 */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的使用,源码如下:
package com.iaiai.activity;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;/** *  * <p> * title: mainmenuview.java * </p> * <p> * e-mail: 176291935@qq.com * </p> * <p> * qq: 176291935 * </p> * <p> * http: iaiai.iteye.com * </p> * <p> * create time: 2011-8-17 * </p> *  * @author 丸子 * @version 0.0.1 */public class mainmenuview extends activity {tabmenu.menubodyadapter[] bodyadapter = new tabmenu.menubodyadapter[3];tabmenu.menutitleadapter titleadapter;tabmenu tabmenu;int seltitle = 0;@overridepublic 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 {@overridepublic void onitemclick(adapterview<?> arg0, view arg1, int arg2,long arg3) {seltitle = arg2;tabmenu.settitleselect(arg2);tabmenu.setbodyadapter(bodyadapter[arg2]);}}class bodyclickevent implements onitemclicklistener {@overridepublic 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(mainmenuview.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}}

更多相关文章

  1. Python3原生编写月份计算工具
  2. 一款常用的 Squid 日志分析工具
  3. GitHub 标星 8K+!一款开源替代 ls 的工具你值得拥有!
  4. Linux 环境下实战 Rsync 备份工具及配置 rsync+inotify 实时同步
  5. Android(安卓)应用程序签名
  6. Android程序员指南(19)
  7. Android(安卓)JNI入门第二篇——Java参数类型与本地参数类型对照
  8. [知识] ADB工具(Android(安卓)Debug Bridge) 详解,使用方法
  9. Android(安卓)adb工具的使用

随机推荐

  1. Android传感器(五):线性加速度传感器
  2. Android中常用的bitmap处理方法
  3. 7.1.3 TimePicker结合案例详解
  4. Android用户和用户组的定义
  5. Android 源码下载遇到 403错误 的解决办
  6. Android判断程序是否第一次启动
  7. Android XMPP 即时通讯
  8. Android裁剪图像实现方法示例
  9. Android自动测试代码
  10. 关于android软键盘隐藏总结