10.5 菜单(menu)资源

源代码目录:src/ch10/MenuResource

在第9章已经介绍了菜单,但只介绍了如何使用Java代码动态创建菜单。实际上,菜单也可以放在资源文件中进行设置,这种资源称为菜单资源。从Android 3.0开始,菜单资源增加了一些与ActionBar有关的一些属性,这些属性会留在ActionBar这章(第18章)详细介绍,本节只介绍菜单资源中与ActionBar无关的属性。

菜单资源文件必须放在res/menu目录中。使用<menu>标签作为菜单资源文件的根节点。除了<menu>标签外,还有另外两个标签用于设置菜单项和分组,这两个标签是<item>和<group>。

<menu>标签没有任何属性,但可以嵌套在<item>标签中,表示一个子菜单。<item>标签中不能再嵌入<item>标签,否则系统会忽略嵌入的<item>标签(并不会抛出异常)。<item>标签的属性含义如下。

android:id:表示菜单项的资源ID。

android:menuCategory:表示菜单项的种类。该属性可取4个值:container、system、secondary和alternative。通过menuCategroy属性可以控制菜单项的位置。例如将属性值设为system,表示该菜单项是系统菜单,应放在其他种类菜单项的后面。

android:orderInCategory:同种类菜单的排列顺序。该属性需要设置一个整数值。例如menuCategory属性值都为system的3个菜单项(item1、item2和item3)。将这3个菜单项的orderInCategory属性值分别设为3、2、1,那么item3会显示在最前面,而item1会显示在最后面。

android:title:菜单项标题(菜单项显示的文本)。

android:titleCondensed:菜单项的短标题。当菜单项标题太长时会显示该属性值。

android:icon:菜单项图标的资源ID。

android:onClick:单击菜单项执行的方法名,该方法只能有一个MenuItem类型的参数。从API Level = 11(Android3.0)开始支持该属性。

android:alphabeticShortcut:菜单项的字母快捷键。

android:numericShortcut:菜单项的数字快捷键。

android:checkable:表示菜单项是否带复选框。该属性可设置的值为true或false。

android:checked:如果菜单项带复选框(checkable属性值为true),该属性表示复选框默认状态是否被选中。可设置的值为true或false。

android:visible:菜单项默认状态是否可视。

android:enabled:菜单项默认状态是否可用(可被触摸)。

<group>标签的属性含义如下:

android:id:表示菜单组的ID。

android:menuCategory:与<item>标签的同名属性含义相同,只是作用域为菜单组。

android:orderInCategory:与<item>标签的同名属性含义相同,只是作用域为菜单组。

android:checkableBehavior:设置该组所有菜单项上显示的选择控件(CheckBox或Radio Button)。如果将该属性值设为all,显示CheckBox控件;如果设为single,显示Radio Button控件;如果设为none,显示正常的菜单项(不显示任何选择控件)。

android:visible:表示当前组中所有菜单项是否显示。该属性可设置的值是true或false。

android:enabled:表示当前组中所有菜单项是否可用。该属性可设置的值是true或false。

下面是一个菜单资源文件的例子。

源代码文件:src/ch10/MenuResource/res/menu/options_menu.xml

<menu xmlns:android="http://schemas.android.com/apk/res/android">

  <item android:id="@+id/mnuFestival" android:title="节日"

    android:icon="@drawable/festival" />

  <group android:id="@+id/mnuFunction">

    <item android:id="@+id/mnuEdit" android:title="编辑" android:icon="@drawable/edit" />

    < !-- 为【删除】菜单项指定了单击方法:onClick_Delete -->

    <item android:id="@+id/mnuDelete" android:title="删除"

      android:icon="@drawable/delete"android:onClick="onClick_Delete" />

    <item android:id="@+id/mnuFinish" android:title="完成"

      android:icon="@drawable/finish" />

  </group>

  <item android:id="@+id/mnuOthers" android:title="其他功能">

    <!-- 定义子菜单 -->

    <menu>

      <!-- 所有的子菜单项都带Radio Button -->

      <group android:checkableBehavior="single">

        <!-- 该菜单项的种类是system(在最后显示),而且RadioButton处于选中状态 -->

        <item android:id="@+id/mnuDiary" android:title="日记"

          android:menuCategory="system" android:checked="true" />

        <item android:id="@+id/mnuAudio" android:title="音频"

          android:orderInCategory="2" />

        <item android:id="@+id/mnuVideo" android:title="视频"

          android:orderInCategory="3" />

      </group>

    </menu>

  </item>

</menu>

在options_menu.xml资源文件中定义了一个选项菜单和一个子菜单。为了显示选项菜单,需要在Activity.onCreateOptionsMenu方法中装载这个菜单资源文件,并指定相应菜单项的单击事件监听器。为了响应“删除”菜单项的单击事件,还需要编写一个单击事件方法。装载选项菜单和相应选项菜单项的完整代码如下:

源代码文件:src/ch10/MenuResource/src/mobile/android/menu/resource/Main.java

// 装载选项菜单

public boolean onCreateOptionsMenu(Menu menu)

{

  MenuInflater menuInflater = getMenuInflater();

  // 装载options_menu.xml文件

  menuInflater.inflate(R.menu.options_menu, menu);

  // 设置“编辑”菜单的单击事件监听器

  menu.findItem(R.id.mnuEdit).setOnMenuItemClickListener(this);

  // 设置子菜单的头部图标

  menu.getItem(4).getSubMenu().setHeaderIcon(R.drawable.icon);

  return true;

}

// “编辑”菜单项的单击事件方法

@Override

public boolean onMenuItemClick(MenuItem item)

{

  Toast.makeText(this, "<" + item.getTitle() + ">被单击", Toast.LENGTH_LONG)

      .show();

  return false;

}

// “删除”菜单项的单击事件方法

public void onClick_Delete(MenuItem item)

{

  Toast.makeText(this, "onClick_Delete",Toast.LENGTH_LONG).show();

}

在上面的代码中通过两种方式获得了在菜单资源文件中定义的菜单项:findItem和getItem。这两个方法分别通过菜单项资源ID和实际显示的索引来获得菜单项(MenuItem对象)。在实际使用时,建议使用findItem方法通过菜单项资源ID获得MenuItem对象。

除了选项菜单和子菜单,上下文菜单也可以使用菜单资源文件定义。下面是一个上下文菜单的资源文件。

源代码文件:src/ch10/MenuResource/res/menu/context_menu.xml

<menu xmlns:android="http://schemas.android.com/apk/res/android">

  <item android:id="@+id/mnuEdit" android:title="编辑" />

  <item android:id="@+id/mnuDelete" android:title="删除" />

  <item android:id="@+id/mnuFinish" android:title="完成" />

</menu>

为了显示上下文菜单,在屏幕上方放一个EditText控件,并在onCreateContextMenu方法中显示上下文菜单,代码如下:

public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo menuInfo)

{

  MenuInflater menuInflater = getMenuInflater();

  // 装载context_menu.xml文件

  menuInflater.inflate(R.menu.context_menu, menu);

  super.onCreateContextMenu(menu, view, menuInfo);

}

最后需要在onCreate事件方法中将上下文菜单注册到EditText控件上,代码如下:

EditText editText = (EditText)findViewById(R.id.edittext);

// 将上下文菜单注册到EditText控件上

registerForContextMenu(editText);

现在运行本例,按模拟器上的Menu菜单,会显示如图10-13所示的选项菜单(未使用与ActionBar关联的Theme)。单击“其他功能”菜单项,会显示如图10-14所示的子菜单。长按EditText控件,会弹出如图10-15所示的上下文菜单。

 

▲图10-13 选项菜单

 

▲图10-14 子菜单

 

▲图10-15 上下文菜单