Android 自定义PopupWindow实现的Menu(TabMenu)

    用过ucweb-android版的人都应该对其特殊的menu有印象,把menu做成tab-menu(支持分页的menu),可以容纳比android传统的menu更丰富的内容(android的menu超过6项则缩略在[更多]里),本文参考网上的例子,对例子进行简化以及封装,使其作为一个复合控件融入自己的framework。

先来看看本文程序运行的效果:
Android 自定义PopupWindow实现的Menu(TabMenu)

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: [email protected] * </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: [email protected] * </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;	@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(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	}}
 

你可能感兴趣的:(java,工作)