定义菜单资源文件
菜单资源文件通常放置在 res\menu 目录下,在 Android Studio 中创建项目时,默认是不能自动创建 menu 目录的,所以需要手动创建。菜单资源的根元素通常使用 <menu></menu> 标记,在该标记中可以包含多个 <item></item> 标记,用于定义菜单项,可以通过表 13.1 所示的各属性来为菜单项设置标题等内容。
属性 | 描述 |
android:id | 用于为菜单项设置 ID,也就是唯一标识 |
android:title | 用于为菜单项设置标题 |
android:alphabeticShortcut | 用于为菜单项指定字符快捷键 |
android:numericShortcut | 用于为菜单项指定数字快捷键 |
android:icon | 用于为菜单项指定图标 |
android:enabled | 用于指定该菜单项是否可用 |
android:checkable | 用于指定该菜单项是否可选 |
android:checked | 用于指定该菜单项是否已选中 |
android:visible | 用于指定该菜单项是否可见 |
使用菜单资源
在 Android 中,定义的菜单资源可以用来创建选项菜单(Option Menu)和上下文菜单(Content Menu)。使用菜单资源创建这两种菜单的方法是不同的,下面分别进行介绍。
选项菜单
当用户单击菜单按钮时,弹出的菜单就是选项菜单。使用菜单资源创建选项菜单的具体步骤如下:
(1)重写 Activity 中的 onCreateOptionsMenu() 方法。在该方法中,首先创建一个用于解析菜单资源文件的 MenuInflater 对象,然后调用该对象的 inflate() 方法解析一个菜单资源文件,并把解析后的菜单保存在 menu 中,关键代码如下:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater=new MenuInflater(this); //实例化一个MenuInflater对象
inflater.inflate(R.menu.optionmenu, menu); //解析菜单文件
return super.onCreateOptionsMenu(menu);
}
(2)重写 onOptionsItemSelected() 方法,用于当菜单项被选择时,做出相应的处理。例如,当菜单项被选择时,弹出一个消息提示框显示被选中菜单项的标题,可以使用下面的代码:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
Toast.makeText(MainActivity.this, item.getTitle(), Toast.LENGTH_SHORT).show();
return super.onOptionsItemSelected(item);
}
上下文菜单
当用户长按组件时,弹出的菜单就是上下文菜单。使用菜单资源创建上下文菜单的具体步骤如下。
(1)在 Activity 的 onCreate() 方法中注册上下文菜单。例如,为文本框组件注册上下文菜单,当长按该文本框时,显示上下文菜单,可以使用下面的代码:
TextView tv=(TextView)findViewById(R.id.show);
registerForContextMenu(tv); //为文本框注册上下文菜单
(2)重写 Activity 中的 onCreateContextMenu() 方法。在该方法中,首先创建一个用于解析菜单资源文件的 MenuInflater 对象,然后调用该对象的 inflate() 方法解析一个菜单资源文件,并把解析后的菜单保存在 menu 中,最后为菜单头设置图标和标题,关键代码如下:
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
MenuInflater inflator=new MenuInflater(this); //实例化一个MenuInflater对象
inflator.inflate(R.menu.menus, menu); //解析菜单文件
menu.setHeaderIcon(R.mipmap.ic_launcher); //为菜单头设置图标
menu.setHeaderTitle("请选择"); //为菜单头设置标题
}
(3)重写 onContextItemSelected() 方法,用于当菜单项被选择时,做出相应的处理。例如,当菜单项被选择时,弹出一个消息提示框显示被选中菜单项的标题,可以使用下面的代码:
@Override
public boolean onContextItemSelected(MenuItem item) {
Toast.makeText(MainActivity.this, item.getTitle(), Toast.LENGTH_SHORT).show();
return super.onContextItemSelected(item);
}
例子
选项菜单
编写menu.xml文件
在 res 目录上单击鼠标右键,在弹出的快捷菜单中选择 New → Android resource directory菜单项,在弹出的对话框中,在 Resource type 类型的下拉列表框中选择 menu,单击 OK 按钮。创建一个 menu 目录,并在该目录中创建一个名称为 menu.xml 的菜单资源文件,在 menu.xml 文件中,定义两个菜单项分别是“设置”和“关于”,显示文字通过字符串资源指定。
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/settings"
android:title="@string/menu_title_settings"></item>
<item
android:id="@+id/regard"
android:title="@string/menu_title_regard"></item>
</menu>
编写MenuResourceActivity
public class MenuResourceActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_menu_resource);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater menuInflater = new MenuInflater(this); //实例化一个MenuInflater对象
menuInflater.inflate(R.menu.menu, menu); //解析菜单文件
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) { //获取选中的菜单id
case R.id.settings:
Toast.makeText(this,"你单击了设置",Toast.LENGTH_SHORT).show();
break;
case R.id.regard:
Toast.makeText(this,"你单击了关于",Toast.LENGTH_SHORT).show();
break;
}
return super.onOptionsItemSelected(item);
}
}
效果
模拟微信朋友圈的消息菜单
编写introduce_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/menu_copy"
android:title="@string/introduce_copy"></item>
<item
android:id="@+id/menu_collect"
android:title="@string/introduce_collect"></item>
<item
android:id="@+id/menu_translate"
android:title="@string/introduce_translate"></item>
<item
android:id="@+id/menu_report"
android:title="@string/introduce_report"></item>
</menu>
编写布局资源文件
添加TextView,用来模拟朋友圈中的一条消息
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/relativeLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp">
<TextView
android:id="@+id/introduce"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="心虽有所觉,但亦作不解"
android:textSize="20sp" />
</RelativeLayout>
编写ContextMenuActivity
重写 onCreateContextMenu() 方法,在该方法中,创建一个用于解析菜单资源文件的 MenuInflater 对象,然后调用该对象的 inflate() 方法解析文本框的菜单资源文件,并把解析后的菜单保存在 menu 中,关键代码如下:
public class ContextMenuActivity extends AppCompatActivity {
TextView introduce; //声明TextView组件
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_context_menu);
introduce = (TextView) findViewById(R.id.introduce);//获取显示消息的TextView组件
registerForContextMenu(introduce); //为文本框注册上下文菜单
}
@Override
//创建上下文菜单
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenu.ContextMenuInfo menuInfo) {
MenuInflater inflater = new MenuInflater(this); //实例化一个MenuInflater对象
inflater.inflate(R.menu.introduce_menu, menu); //解析菜单文件
}
@Override
public boolean onContextItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_copy: //选中介绍文字菜单中的"复制"菜单项时
Toast.makeText(this, "已复制", Toast.LENGTH_SHORT).show();
break;
case R.id.menu_collect: //选中介绍文字菜单中的"收藏"菜单项时
Toast.makeText(this,"已收藏",Toast.LENGTH_SHORT).show();
break;
case R.id.menu_translate: //选中介绍文字菜单中的"收藏"菜单项时
Toast.makeText(this,"已翻译",Toast.LENGTH_SHORT).show();
break;
case R.id.menu_report: //选中介绍文字菜单中的"收藏"菜单项时
Toast.makeText(this,"已举报",Toast.LENGTH_SHORT).show();
break;
}
return true;
}
}