好记性不如铅笔头

android, 编程

Android应用开发笔记:menu

最近想用menu来做一些好玩的东西,就备忘下android的menu的各种用法。

菜单是用户界面中最常见的元素,使用也非常频繁,在Android中,菜单被分为如下三种,

选项菜单(OptionsMenu)、上下文菜单(ContextMenu)和子菜单(SubMenu)。

CONTENTS

OptionsMenu

1)通过xml文件来实现

XML文件如下

menu的XML文件的定义可以参考【 http://www.cnblogs.com/xirihanlin/archive/2010/06/25/1765261.html 】

<menu xmlns:android="http://schemas.android.com/apk/res/android" >
    <item
        android:id="@+id/action_settings"
        android:orderInCategory="100" 
        android:showAsAction="never"
        android:title="@string/action_settings"/>
<item android:id="@+id/item1" android:title="a" android:icon="@drawable/weather10"/>
<item android:id="@+id/item2" android:title="b"/>
<item android:id="@+id/item3" android:title="c"/>
<item android:id="@+id/item4" android:title="d"/>
<item android:id="@+id/item5" android:title="e"/>
<item android:id="@+id/item6" android:title="f"/>
<item android:id="@+id/item7" android:title="g"/>
</menu>

 Activity代码:

@Override
public boolean onCreateOptionsMenu(Menu menu) 
{
	getMenuInflater().inflate(R.menu.main, menu);
	return true;//返回true会让菜单显示,false不会让菜单显示
}
@Override
public boolean onOptionsItemSelected(MenuItem item) 
{
	if (item.getItemId() == R.id.item1)
	{
		Toast.makeText(this, item.getTitle(), Toast.LENGTH_SHORT).show();
	}
	return super.onOptionsItemSelected(item);
}
public void onClick(View v)
{
	openOptionsMenu();//可以通过该方法让菜单显示
}

备注:
1)menu是可以通过 android:orderInCategory 设置顺序的,越小越靠前。
2)menu的icon只有在第一级别menu上才会显示(第1-5个menu),点击更多出现的menuitem不会显示icon。

2)通过代码实现

Activity代码

@Override
public boolean onCreateOptionsMenu(Menu menu) 
{
	menu.add(Menu.NONE, 1, Menu.NONE, "t1").setIcon(android.R.drawable.ic_menu_edit);
	menu.add(Menu.NONE, 2, Menu.NONE, "t2").setIcon(R.drawable.weather6);
	menu.add(Menu.NONE, 3, Menu.NONE, "t3");
	menu.add(Menu.NONE, 4, Menu.NONE, "t4");
	menu.add(Menu.NONE, 5, Menu.NONE, "t5");
	return true;
}

 备注:

1)以android.R开头的资源是系统提供的,我们自己提供的资源是以R开头的

3)使用gridview仿制一个menu

参考【 http://www.cnblogs.com/salam/archive/2011/04/04/2005329.html 】

核心思想是通过在一个gridview上面添加item的方式,使用dialog仿制出一个menu的样式。

1)建立一个gridview,用来作为menu的主layout(menugrid.xml)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
    <GridView
        android:id="@+id/gridview"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:gravity="center"
        android:horizontalSpacing="10dip"
        android:numColumns="4"
        android:stretchMode="columnWidth"
        android:verticalSpacing="10dip" />
</LinearLayout>

 2)建立一个自定自定义的layout,用来作为每个item的样式(menuitem.xml)

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/RelativeLayout_Item"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:paddingBottom="5dip" >

    <ImageView
        android:id="@+id/item_image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true" >
    </ImageView>

    <TextView
        android:id="@+id/item_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/item_image"
        android:layout_centerHorizontal="true"
        android:text="选项" >
    </TextView>
</RelativeLayout>

 3)在Activity中声明相关的变量

	private boolean secondPage = false;// menu菜单翻页控制
	private AlertDialog menuDialog;// menu菜单Dialog
	private GridView menuGrid;
	private View menuView;

int[] menu_image_array1 = { R.drawable.weather1, R.drawable.weather2,
		R.drawable.weather3, R.drawable.weather4, R.drawable.weather5,
		R.drawable.weather6, R.drawable.weather7, R.drawable.weather8, };
String[] menu_name_array1 = { "weather1", "weather2", "weather3",
		"weather4", "weather5", "weather6", "weather7", "more", };
int[] menu_image_array2 = { R.drawable.weather9, R.drawable.weather10,
		R.drawable.ic_launcher, };
String[] menu_name_array2 = { "weather9", "back", "quit" };

 4)建立一个dialog,将自定义的gridview贴到上面

@Override
protected void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.activity_main);
	button1 = (Button) findViewById(R.id.button1);
	button1.setOnClickListener(new OnClickListener() {
		public void onClick(View v) {
			openOptionsMenu();
		}
	});

	menuView = View.inflate(this, R.layout.menugrid, null);
	// 创建AlertDialog
	menuDialog = new AlertDialog.Builder(this).create();
	menuDialog.setView(menuView);
	menuDialog.setOnKeyListener(new OnKeyListener() {
		public boolean onKey(DialogInterface dialog, int keyCode,
				KeyEvent event) {
			if (keyCode == KeyEvent.KEYCODE_MENU)// 监听按键
				dialog.dismiss();
			return false;
		}
	});

	menuGrid = (GridView) menuView.findViewById(R.id.gridview);
	menuGrid.setAdapter(getMenuAdapter(menu_name_array1, menu_image_array1));
	menuGrid.setOnItemClickListener(new OnItemClickListener() {
		public void onItemClick(AdapterView<?> arg0, View item, int arg2,
				long arg3) 
		{
			//arg2标识item在view中的顺序,以0开始。
			switch (arg2) 
			{
				case 7:// more
				{
					if (!secondPage) {
						menuGrid.setAdapter(getMenuAdapter(menu_name_array2,
								menu_image_array2));
						secondPage = true;
					}
					break;
				}
				case 1:// back
					if (secondPage) {
						menuGrid.setAdapter(getMenuAdapter(menu_name_array1,
								menu_image_array1));
						secondPage = false;
					}
					break;
				case 2:// quit
				{
					if (secondPage)
					{
						menuDialog.dismiss();
						break;
					}
				}
				default: 
				{

				}
			}
		}
	});
}
private SimpleAdapter getMenuAdapter(String[] menuNameArray,
		int[] imageResourceArray) {
	ArrayList> data = new ArrayList>();
	for (int i = 0; i < menuNameArray.length; i++) {
		HashMap map = new HashMap();
		map.put("itemImage", imageResourceArray[i]);
		map.put("itemText", menuNameArray[i]);
		data.add(map);
	}
	SimpleAdapter simperAdapter = new SimpleAdapter(this, data,
			R.layout.menuitem, new String[] { "itemImage", "itemText" },
			new int[] { R.id.item_image, R.id.item_text });
	return simperAdapter;
}

 代码比较复杂,但是主要是onclick的消息比较长,去掉item的处理之后,就很短了。

5)activity回调函数的处理,比较特殊一点

@Override
public boolean onCreateOptionsMenu(Menu menu) {
	menu.add(Menu.NONE, 5, Menu.NONE, "t5");
	return true;
}
@Override
public boolean onMenuOpened(int featureId, Menu menu) {
	menuDialog.show();
	return false;// 返回为true 则显示系统menu
}

示例:

   

备注:
1)如果直接调用openOptionsMenu(),也可以在onCreateOptionsMenu()返回为false的情况下弹出dialog,但是此情形下点击menu会出现dialog一闪而退的情况。具体的逻辑没有查过,但是我感觉一般不会这么用。

4)自定义系统菜单的背景

http://blog.csdn.net/sodino/article/details/6165132 】我没有使用过,先备忘下。

5)添加子菜单

添加子菜单比较和添加菜单项比较相似。

@Override
public boolean onCreateOptionsMenu(Menu menu) {
	SubMenu sm = menu.addSubMenu("submenu").setIcon(R.drawable.weather1);
	sm.add(Menu.NONE, 1, Menu.NONE,"t1").setIcon(android.R.drawable.ic_menu_edit);
	 menu.add(Menu.NONE, 2, Menu.NONE, "t2").setIcon(R.drawable.weather6);
	 sm.add(Menu.NONE, 3, Menu.NONE, "t3"); 
	 menu.add(Menu.NONE, 4, Menu.NONE, "t4");
	 menu.add(Menu.NONE, 5, Menu.NONE, "t5");
	return true;
}

 ContextMenu

1)通过代码实现

public class MainActivity extends Activity {
	private TextView textView1;

	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		textView1 = (TextView)findViewById(R.id.textView1);
		registerForContextMenu(textView1);
@Override
 public void onCreateContextMenu(ContextMenu menu, View v,
 ContextMenuInfo menuInfo) 
 {
 if (v.getId() == R.id.textView1)
 {
 menu.setHeaderIcon(R.drawable.weather7);
 menu.setHeaderTitle("这是一个ContextMenu");  
 
 SubMenu sm = menu.addSubMenu("submenu");
 sm.add(Menu.NONE, 4, Menu.NONE, "t4");
 
 menu.add(3, 200, 200, "Context Menu 1").setIcon(R.drawable.weather2);  
 menu.add(3, 201, 201, "Context Menu 2");  
 }
 
 super.onCreateContextMenu(menu, v, menuInfo);
 }

 @Override
 public boolean onContextItemSelected(MenuItem item) 
 {
 if (item.getItemId() == 200)
 {
 Toast.makeText(this, item.getTitle(), Toast.LENGTH_SHORT).show();
 }
 return super.onContextItemSelected(item);
 }
 @Override
 public void onContextMenuClosed(Menu menu) 
 {
 super.onContextMenuClosed(menu);
 }

发表评论

14 + 6 =

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据