7.16.Menu(菜单组件)
在一个菜单之中最多只会显示2排3列的菜单项,如果现在的菜单项超出了6,则超出部分会自动的隐藏,而且会自动出现一个“更多”的菜单项提示用户。
在Android中,菜单一共分为三类:选项菜单(OptionMenu)、上下文菜单(ContextMenu)和子菜单(SubMenu)
7.16.1 选项菜单(OptionsMenu)
范例一:通过程序生成选项菜单
配置:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/MyLayout" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <TextView android:id="@+id/txt" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="按下Menu键出现选项菜单"/> </LinearLayout> |
Activity:
package com.makyan.demo; import android.app.Activity; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.widget.Toast; public class OperationsMenuActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); super.setContentView(R.layout.activity_operations_menu); } @Override public boolean onCreateOptionsMenu(Menu menu) { // 显示菜单 menu.add(Menu.NONE, // 菜单不分组 Menu.FIRST + 1, // 菜单项ID 1, // 菜单编号 "删除") // 显示标题 .setIcon(android.R.drawable.ic_menu_delete); // 设置图标 menu.add(Menu.NONE, Menu.FIRST + 2, 2, "保存").setIcon( android.R.drawable.ic_menu_save); // 设置菜单项 menu.add(Menu.NONE, Menu.FIRST + 3, 3, "帮助").setIcon( android.R.drawable.ic_menu_help); // 设置菜单项 menu.add(Menu.NONE, Menu.FIRST + 4, 4, "添加").setIcon( android.R.drawable.ic_menu_add); // 设置菜单项 menu.add(Menu.NONE, Menu.FIRST + 5, 5, "详细").setIcon( android.R.drawable.ic_menu_info_details); // 设置菜单项 menu.add(Menu.NONE, Menu.FIRST + 6, 6, "发送").setIcon( android.R.drawable.ic_menu_send); // 设置菜单项 menu.add(Menu.NONE, Menu.FIRST + 7, 7, "编辑").setIcon( android.R.drawable.ic_menu_edit); // 设置菜单项 return true; // 菜单显示 } @Override public boolean onOptionsItemSelected(MenuItem item) { // 选中某个菜单项 switch (item.getItemId()) { // 判断菜单项ID case Menu.FIRST + 1: Toast.makeText(this, "您选择的是“删除菜单”项。", Toast.LENGTH_LONG).show(); break; case Menu.FIRST + 2: Toast.makeText(this, "您选择的是“保存菜单”项。", Toast.LENGTH_LONG).show(); break; case Menu.FIRST + 3: Toast.makeText(this, "您选择的是“帮助菜单”项。", Toast.LENGTH_LONG).show(); break; case Menu.FIRST + 4: Toast.makeText(this, "您选择的是“添加菜单”项。", Toast.LENGTH_LONG).show(); break; case Menu.FIRST + 5: Toast.makeText(this, "您选择的是“详细菜单”项。", Toast.LENGTH_LONG).show(); break; case Menu.FIRST + 6: Toast.makeText(this, "您选择的是“发送菜单”项。", Toast.LENGTH_LONG).show(); break; case Menu.FIRST + 7: Toast.makeText(this, "您选择的是“设置菜单”项。", Toast.LENGTH_LONG).show(); break; } return false; } @Override public void onOptionsMenuClosed(Menu menu) { // 菜单退出时调用 Toast.makeText(this, "选项菜单关闭了", Toast.LENGTH_LONG).show(); } @Override public boolean onPrepareOptionsMenu(Menu menu) { // 菜单显示前调用 Toast.makeText(this, "在菜单显示(onCreateOptionsMenu()方法)之前会调用此操作,可以在此操作之中完成一些预处理操作。",Toast.LENGTH_LONG).show(); return true; // 调用onCreateOptionsMenu() } } |
onPrepareOptionsMenu(Menu menu)在创建菜单前操作,
onOptionsMenuClosed(Menu menu)在关闭菜单后操作
演示效果:
范例二:通过配置生成选项菜单
在创建菜单时,可以使用MenuInflater来获取配置文件填充菜单
getMenuInflater().inflate(R.menu.operations_menu, menu); |
配置:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/MyLayout" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <TextView android:id="@+id/txt" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="按下Menu键出现选项菜单"/> </LinearLayout> |
在res/menu下创建菜单配置operations_menu.xml
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/item01" android:title="添加" android:icon="@android:drawable/ic_menu_add" /> <item android:id="@+id/item02" android:title="保存" android:icon="@android:drawable/ic_menu_save" /> <item android:id="@+id/item03" android:title="编辑" android:icon="@android:drawable/ic_menu_edit" /> <item android:id="@+id/item04" android:title="详细" android:icon="@android:drawable/ic_menu_info_details" /> <item android:id="@+id/item05" android:title="删除" android:icon="@android:drawable/ic_menu_delete" /> <item android:id="@+id/item06" android:title="发送" android:icon="@android:drawable/ic_menu_send" /> <item android:id="@+id/item06" android:title="帮助" android:icon="@android:drawable/ic_menu_help" /> <item android:id="@+id/item07" android:title="发送" android:icon="@android:drawable/ic_menu_send" /> </menu> |
Activity:
以下代码和以上的Activity程序就只在创建菜单时获取菜单有区别:
package com.makyan.demo; import android.app.Activity; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.widget.Toast; public class OperationsMenuActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); super.setContentView(R.layout.activity_operations_menu); } @Override public boolean onCreateOptionsMenu(Menu menu) { // 显示菜单 super.getMenuInflater().inflate(R.menu.operations_menu, menu); // 填充菜单项 return true; // 菜单显示 } @Override public boolean onOptionsItemSelected(MenuItem item) { // 选中某个菜单项 switch (item.getItemId()) { // 判断菜单项ID case Menu.FIRST + 1: Toast.makeText(this, "您选择的是“删除菜单”项。", Toast.LENGTH_LONG).show(); break; case Menu.FIRST + 2: Toast.makeText(this, "您选择的是“保存菜单”项。", Toast.LENGTH_LONG).show(); break; case Menu.FIRST + 3: Toast.makeText(this, "您选择的是“帮助菜单”项。", Toast.LENGTH_LONG).show(); break; case Menu.FIRST + 4: Toast.makeText(this, "您选择的是“添加菜单”项。", Toast.LENGTH_LONG).show(); break; case Menu.FIRST + 5: Toast.makeText(this, "您选择的是“详细菜单”项。", Toast.LENGTH_LONG).show(); break; case Menu.FIRST + 6: Toast.makeText(this, "您选择的是“发送菜单”项。", Toast.LENGTH_LONG).show(); break; case Menu.FIRST + 7: Toast.makeText(this, "您选择的是“设置菜单”项。", Toast.LENGTH_LONG).show(); break; } return false; } @Override public void onOptionsMenuClosed(Menu menu) { // 菜单退出时调用 Toast.makeText(this, "选项菜单关闭了", Toast.LENGTH_LONG).show(); } @Override public boolean onPrepareOptionsMenu(Menu menu) { // 菜单显示前调用 Toast.makeText(this, "在菜单显示(onCreateOptionsMenu()方法)之前会调用此操作,可以在此操作之中完成一些预处理操作。",Toast.LENGTH_LONG).show(); return true; // 调用onCreateOptionsMenu() } } |
7.16.2 上下文菜单(ContextMenu)
范例一:通过程序获取上下文菜单
创建菜单、关闭、创建菜单前的操作跟选项菜单没有区别,区别在于,需要一个组件,并将数据设置在组件的适配器中,并对此组件进行注册:
Activity:
package com.makyan.demo; import android.app.Activity; import android.os.Bundle; import android.view.ContextMenu; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.ArrayAdapter; import android.widget.ListView; import android.widget.Toast; public class ContextMenuActivity extends Activity { private String data[] = { "杨雄工作室", "www.makyanjava.cn", "讲师:杨雄进", "中国高校讲课联盟", "www. makyanjava.com"}; // 定义显示的数据 private ListView listView; // 定义ListView组件 @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); listView = new ListView(this) ; // 实例化组件 listView.setAdapter(new ArrayAdapter<String>(this, // 将数据包装 android.R.layout.simple_expandable_list_item_1, // 每行显示一条数据 this.data)); // 设置组件内容 super.setContentView(this.listView); // 将组件添加到屏幕之中 super.registerForContextMenu(this.listView) ; // 注册上下文菜单 } @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { // 显示菜单 super.onCreateContextMenu(menu, v, menuInfo) ; menu.setHeaderTitle("信息操作") ; // 设置显示信息头 menu.add(Menu.NONE, Menu.FIRST + 1, 1, "添加联系人"); // 设置菜单项 menu.add(Menu.NONE, Menu.FIRST + 2, 2, "查看详情"); // 设置菜单项 menu.add(Menu.NONE, Menu.FIRST + 3, 3, "删除信息"); // 设置菜单项 menu.add(Menu.NONE, Menu.FIRST + 4, 4, "另存为"); // 设置菜单项 menu.add(Menu.NONE, Menu.FIRST + 5, 5, "编辑"); // 设置菜单项 } @Override public boolean onContextItemSelected(MenuItem item) { // 选中某个菜单项 switch (item.getItemId()) { // 判断菜单项ID case Menu.FIRST + 1: Toast.makeText(this, "您选择的是“添加联系人”项。", Toast.LENGTH_LONG).show(); break; case Menu.FIRST + 2: Toast.makeText(this, "您选择的是“查看详情”项。", Toast.LENGTH_LONG).show(); break; case Menu.FIRST + 3: Toast.makeText(this, "您选择的是“删除信息”项。", Toast.LENGTH_LONG).show(); break; case Menu.FIRST + 4: Toast.makeText(this, "您选择的是“另存为”项。", Toast.LENGTH_LONG).show(); break; case Menu.FIRST + 5: Toast.makeText(this, "您选择的是“编辑”项。", Toast.LENGTH_LONG).show(); break; } return false; } @Override public void onContextMenuClosed(Menu menu) { // 菜单退出时调用 Toast.makeText(this, "上下文菜单关闭了", Toast.LENGTH_LONG).show(); } } |
演示效果就不贴了,很简单。
长按ListView中的某一项后,
范例二:通过配置来设置上下文菜单:
同样的道理,在创建菜单时,可以使用MenuInflater来获取配置文件填充菜单
在res/menu下创建菜单文件context_menu.xml
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/item01" android:title="添加联系人"/> <item android:id="@+id/item02" android:title="查看详情"/> <item android:id="@+id/item03" android:title="删除信息"/> <item android:id="@+id/item04" android:title="另存为"/> <item android:id="@+id/item05" android:title="编辑"/> </menu> |
Activity程序:
package com.makyan.demo; import android.app.Activity; import android.os.Bundle; import android.view.ContextMenu; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.ArrayAdapter; import android.widget.ListView; import android.widget.Toast; public class ContextMenuActivity extends Activity { private String data[] = { "杨雄工作室", "www.makyanjava.cn", "讲师:杨雄进", "中国高校讲课联盟", "www.makyanjava.com"}; // 定义显示的数据 private ListView listView; // 定义ListView组件 @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.listView = new ListView(this) ; // 实例化组件 listView.setAdapter(new ArrayAdapter<String>(this, // 将数据包装 android.R.layout.simple_expandable_list_item_1, // 每行显示一条数据 this.data)); // 设置组件内容 super.setContentView(this.listView); // 将组件添加到屏幕之中 super.registerForContextMenu(this.listView) ; // 注册上下文菜单 } @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { // 显示菜单 super.onCreateContextMenu(menu, v, menuInfo) ; menu.setHeaderTitle("信息操作") ; // 设置显示信息头 super.getMenuInflater().inflate(R.menu.context_menu, menu); // 填充菜单项 } @Override public boolean onContextItemSelected(MenuItem item) { // 选中某个菜单项 switch (item.getItemId()) { // 判断菜单项ID case Menu.FIRST + 1: Toast.makeText(this, "您选择的是“添加联系人”项。", Toast.LENGTH_LONG).show(); break; case Menu.FIRST + 2: Toast.makeText(this, "您选择的是“查看详情”项。", Toast.LENGTH_LONG).show(); break; case Menu.FIRST + 3: Toast.makeText(this, "您选择的是“删除信息”项。", Toast.LENGTH_LONG).show(); break; case Menu.FIRST + 4: Toast.makeText(this, "您选择的是“另存为”项。", Toast.LENGTH_LONG).show(); break; case Menu.FIRST + 5: Toast.makeText(this, "您选择的是“编辑”项。", Toast.LENGTH_LONG).show(); break; } return false; } @Override public void onContextMenuClosed(Menu menu) { // 菜单退出时调用 Toast.makeText(this, "上下文菜单关闭了", Toast.LENGTH_LONG).show(); } } |
7.16.3 子菜单(SubMenu)
范例一:为每个菜单定义多个子菜单
Activity:
package com.makyan.demo; import android.app.Activity; import android.view.Menu; import android.view.MenuItem; import android.view.SubMenu; import android.widget.Toast; public class SubMenuActivity extends Activity { @Override public boolean onCreateOptionsMenu(Menu menu) { // 显示菜单 SubMenu fileMenu = menu.addSubMenu("文件"); // 菜单 SubMenu editMenu = menu.addSubMenu("编辑"); // 菜单 fileMenu.add(Menu.NONE, Menu.FIRST + 1, 1, "新建") ; // 子菜单项 fileMenu.add(Menu.NONE, Menu.FIRST + 2, 2, "打开") ; // 子菜单项 fileMenu.add(Menu.NONE, Menu.FIRST + 3, 3, "保存") ; // 子菜单项 editMenu.add(Menu.NONE, Menu.FIRST + 4, 4, "撤消"); // 子菜单项 editMenu.add(Menu.NONE, Menu.FIRST + 5, 5, "恢复"); // 子菜单项 return true ; } @Override public boolean onOptionsItemSelected(MenuItem item) { // 选中某个菜单项 switch (item.getItemId()) { // 判断菜单项ID case Menu.FIRST + 1: Toast.makeText(this, "您选择的是“添加联系人”项。", Toast.LENGTH_LONG).show(); break; case Menu.FIRST + 2: Toast.makeText(this, "您选择的是“查看详情”项。", Toast.LENGTH_LONG).show(); break; case Menu.FIRST + 3: Toast.makeText(this, "您选择的是“删除信息”项。", Toast.LENGTH_LONG).show(); break; case Menu.FIRST + 4: Toast.makeText(this, "您选择的是“另存为”项。", Toast.LENGTH_LONG).show(); break; case Menu.FIRST + 5: Toast.makeText(this, "您选择的是“编辑”项。", Toast.LENGTH_LONG).show(); break; } return false; } } |
范例二:通过配置获取子菜单选项
同样的道理,在创建菜单时,可以使用MenuInflater来获取配置文件填充菜单
配置:
Res/menu/editmenu.xml
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/item04" android:title="撤消" /> <item android:id="@+id/item05" android:title="恢复" /> </menu> |
Res/menu/filemenu.xml
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/item01" android:title="新建"/> <item android:id="@+id/item02" android:title="打开" /> <item android:id="@+id/item03" android:title="保存" /> </menu> |
Activity:
package com.makyan.demo; import android.app.Activity; import android.view.Menu; import android.view.MenuItem; import android.view.SubMenu; import android.widget.Toast; public class SubMenuActivity extends Activity { @Override public boolean onCreateOptionsMenu(Menu menu) { // 显示菜单 SubMenu fileMenu = menu.addSubMenu("文件"); // 子菜单 SubMenu editMenu = menu.addSubMenu("编辑"); // 子菜单 super.getMenuInflater().inflate(R.menu.filemenu, fileMenu) ; // 设置菜单项 super.getMenuInflater().inflate(R.menu.editmenu, editMenu) ; // 设置菜单项 return true ; } @Override public boolean onOptionsItemSelected(MenuItem item) { // 选中某个菜单项 switch (item.getItemId()) { // 判断菜单项ID case Menu.FIRST + 1: Toast.makeText(this, "您选择的是“添加联系人”项。", Toast.LENGTH_LONG).show(); break; case Menu.FIRST + 2: Toast.makeText(this, "您选择的是“查看详情”项。", Toast.LENGTH_LONG).show(); break; case Menu.FIRST + 3: Toast.makeText(this, "您选择的是“删除信息”项。", Toast.LENGTH_LONG).show(); break; case Menu.FIRST + 4: Toast.makeText(this, "您选择的是“另存为”项。", Toast.LENGTH_LONG).show(); break; case Menu.FIRST + 5: Toast.makeText(this, "您选择的是“编辑”项。", Toast.LENGTH_LONG).show(); break; } return false; } } |
演示效果同上