菜单是许多应用程序不可或缺的一部分,Android中更是如此,所有搭载Android系统的手机甚至都要有一个"Menu"键,由此可见菜单在Android程序中的特殊性。Android SDK提供的菜单有如下几种:
1 选项菜单:最常规的菜单,android中把它叫做option menu
2 子菜单:android中点击子菜单将弹出悬浮窗口显示子菜单项。子菜单不支持嵌套,即子菜单中不能再包括其他子菜单。
3 上下文菜单:android中长按视图控件后出现的菜单,windows点击右键弹出的菜单即上下文菜单
4 图标菜单:这个比较简单,就是带icon的菜单项,需要注意的是子菜单项、上下文菜单项、扩展菜单项均无法显示图标。
创建options menu
之前提到,Android的activity已经为我们提前创建好了android.view.Menu对象,并提供了回调方法onCreateOptionsMenu(Menu menu)供我们初始化菜单的内容。该方法只会在选项菜单第一次显示的时候被执行,如果你需要动态改变选项菜单的内容,请使用 onPrepareOptionsMenu(Menu menu)。
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
-
- super.onCreateOptionsMenu(menu);
-
-
-
-
- menu.add(0, MENUITEM1, MENUITEM1, "关于");
- menu.add(0, MENUITEM2, MENUITEM2, "帮助");
- menu.add(0, MENUITEM3, MENUITEM3, "更多");
-
- return true;
- }
可以对Menu进行分组:
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- super.onCreateOptionsMenu(menu);
-
- int group1 = 1;
- int gourp2 = 2;
- menu.add(group1, 1, 1, "item 1");
- menu.add(group1, 2, 2, "item 2");
- menu.add(gourp2, 3, 3, "item 3");
- menu.add(gourp2, 4, 4, "item 4");
- return true;
- }
分组之后就能使用menu中提供的方法对组进行操作了,如下:menu.removeGroup(group1); //删除一组菜单
- menu.removeGroup(group1);
- menu.setGroupVisible(gourp2, visible);
- menu.setGroupEnabled(gourp2, enabled);
- menu.setGroupCheckable(gourp2, checkable, exclusive);
响应菜单项
android提供了多种响应菜单项的方式,下面一一介绍
1、通过onOptionsItemSelected方法
使用的最多方法是重写activity类的 onOptionsItemSelected(Menu Item)回调方法,每当有菜单项被点击时,android就会调用该方法,并传入被点击菜单项。
@Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
-
- case MENUITEM1:
- break;
- case MENUITEM2:
- break;
- case MENUITEM3:
- break;
- default:
-
- return super.onOptionsItemSelected(item);
- }
-
- return true;
- }
2.使用监听器
虽然第一种方法是推荐使用的方法,android还是提供了类似java swing的监听器方式来响应菜单。使用监听器的方式分为两步:
第一步:创建监听器类
- class MenuItemListener implements OnMenuItemClickListener {
-
- @Override
- public boolean onMenuItemClick(MenuItem item) {
- return false;
- }
- }
第二步:为菜单项注册监听器
- menu.getItem(0).setOnMenuItemClickListener(new MenuItemListener());
3.使用Intent响应菜单
- menu.getItem(1).setIntent(new Intent());
子菜单sub Menu
Android支持子菜单,你可以通过addSubMenu(int groupId, int itemId, int order, int titleRes)方法创建和响应子菜单。
-
-
-
-
- @Override
- public boolean onPrepareOptionsMenu(Menu menu) {
- Resources res = getBaseContext().getResources();
-
-
-
-
- SubMenu about = menu.addSubMenu(0, MENUITEM1, MENUITEM1, "关于");
- SubMenu help = menu.addSubMenu(0, MENUITEM2, MENUITEM2, "帮助");
- SubMenu more = menu.addSubMenu(0, MENUITEM3, MENUITEM3, "更多");
-
- about.setIcon(res.getDrawable(R.drawable.ic_launcher));
- help.setIcon(res.getDrawable(R.drawable.ic_launcher));
- more.setIcon(res.getDrawable(R.drawable.ic_launcher));
-
-
- MenuItem display = more.add(0, MENUITEM3, MENUITEM3, "设置");
- display.setIcon(R.drawable.ic_launcher);
- more.add(0, MENUITEM3, MENUITEM3, "退出");
- more.setHeaderIcon(R.drawable.ic_launcher);
-
- return true;
- }
Menu可以包含多个SubMenu,SubMenu可以包含多个MenuItem,但是SubMenu不能包含SubMenu,及子菜单不能嵌套!
图标菜单icon Menu
Android支持在菜单上显示各种各样的图标,这一点我们在上面创建子菜单时已经用到了。图标菜单严格上说并不算是一种菜单的新类型,它的使用也很简单,之所以单独设一节是为了说明使用Icon的一些限制。Android中并不是所谓的菜单项都能加上图标,以下菜单项都是不可以的(这并不意味着程序会报错,而是运行时图标得不到显示):
· 扩展的菜单项
· 子菜单的菜单项
· 上下文菜单的菜单项
除此以外,带Icon的菜单项不能加上复选框(check mark)。
上下文菜单ContextMenu
android是通过长按某个视图元素来弹出上下文菜单的,图标和子菜单都无法用在Android的上下文菜单项中。
上下文菜单继承了android.view.Menu,因此我们可以像操作Options Menu那样给上下文菜单增加菜单项。上下文菜单与Options Menu最大的不同在于,Options Menu的拥有者是Activity,而上下文菜单的拥有者是Activity中的View。每个Activity有且只有一个Options Menu,它为整个Activity服务。而一个Activity往往有多个View,并不是每个View都有上下文菜单,这就需要我们显示地通过registerForContextMenu(Viewview)来指定。
尽管上下文菜单的拥有者是View,生成上下文菜单却是通过Activity中的onCreateContextMenu(ContextMenu menu, View v,ContextMenu.ContextMenuInfo menuInfo)方法,该方法很像生成Options Menu的onCreateOptionsMenu(Menu menu)方法。两者的不同在于,onCreateOptionsMenu只在用户第一次按“Menu”键时被调用,而onCreateContextMenu会在用户每一次长按View时被调用,而且View必须已经注册了上下文菜单。
另一个值得注意的就是ContextMenuInfo,该类的对象被传入onCreateContextMenu(ContextMenu menu, View v,ContextMenu.ContextMenuInfo menuInfo)方法,那么它有什么用呢?有时候,视图元素需要向上下文菜单传递一些信息,比如该View对应DB记录的ID等,这就要使用ContextMenuInfo。需要传递额外信息的View需要重写getContextMenuInfo()方法,返回一个带有数据的ContextMenuInfo实现类对象。
1.在activity的onCreate(...)方法中为一个view注册上下文菜单
- public class MyListActivity extends ListActivity {
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.two);
- simpleShowList();
-
- this.registerForContextMenu(getListView());
- }
-
- private void simpleShowList() {
- String[] item = new String[] { "ListItem1", "ListItem2", "ListItem3", ListItem4" };
- ArrayAdapter adapter = new ArrayAdapter(this,
- android.R.layout.simple_list_item_1, item);
- this.setListAdapter(adapter);
- }
- }
2.在onCreateContextMenuInfo(...)中生成上下文菜单。
- @Override
- public void onCreateContextMenu(ContextMenu menu, View v,
- ContextMenuInfo menuInfo) {
- menu.setHeaderTitle("文件操作");
- menu.add(0, 1, Menu.NONE, "发送");
- menu.add(0, 2, Menu.NONE, "复制");
- menu.add(0, 3, Menu.NONE, "重命名");
- menu.add(0, 4, Menu.NONE, "删除");
- }
3.在onContextItemSelected(...)中响应上下文菜单项。
- @Override
- public boolean onContextItemSelected(MenuItem item) {
-
- AdapterContextMenuInfo menuInfo = (AdapterContextMenuInfo) item.getMenuInfo();
- switch (item.getItemId()) {
- case 1:
- break;
- case 2:
- break;
- case 3:
- break;
- case 4:
- break;
- default:
- return super.onContextItemSelected(item);
- }
- return true;
- }
Menu关闭
如果需要动态的显示菜单可以在菜单关闭时进行相应的清除处理:
- @Override
- public void onOptionsMenuClosed(Menu menu) {
- menu.clear();
- super.onOptionsMenuClosed(menu);
- }