• Android提供了两种创建菜单的方式,一种是在Java代码中创建,一种使用XML资源文件定义。上面的实例都是在Java代码中创建菜单,在Java代码中创建菜单存在如下不足。
  • 在Java代码中定义菜单、菜单项,必然导致代码臃肿。
  • 需要程序员采用硬编码的方式为每个菜单项分配ID、为每个菜单组分配ID,这种方式导致应用可扩展性、可维护性降低。

一般推荐使用XML资源文件来定义菜单,这种方式可以提高更好的解耦。

菜单资源文件通常应该放在/res/menu目录下,菜单资源的根元素通常是<menu.../>元素,<menu.../>元素无须指定任何属性。<menu.../>元素内可包含如下子元素。

  • <item.../>元素:定义菜单项。
  • <group.../>子元素:将多个<item.../>定义的菜单包装成一个菜单组。<group.../>子元素用于控制整组菜单的行为,该元素可以指定如下常用属性。
  • checkableBehavior:指定该组菜单的选择行为。可指定为none(不可选)、all(多选)和single(单选)三个值。
  • menuCategory:对菜单进行分类,指定菜单的优先级。有效值为container、system、secondary和alternative。
  • visible:指定改组菜单是否可见。
  • enable:指定该组菜单是否可用。

<item.../>元素用于指定一份菜单项,<item.../>元素又可包含<menu.../>元素,位于<item.../>元素内部的<menu.../>就代表子菜单。

<item.../>元素可以指定如下常用属性。

  • android:id:为菜单项指定一个唯一标识。
  • android:title:指定菜单项的标题。
  • android:icon:指定菜单项的图标。
  • android:alphabeticShortcut:为菜单项指定字符快捷键。
  • android:numericShortcut:为菜单项指定数字快捷键。
  • android:checkable:设置该菜单项是否可选。
  • android:checked:设置该菜单项是否已选中。
  • android:visible:设置该菜单项是否可见。
  • android:enable:设置该菜单项是否可用。

一旦在程序中定义了菜单资源后,接下来还是重写onCreateOptionsMenu(用于创建选项菜单)、onCreateContextMenu(用于创建上下文菜单)方法,在这些方法中调用MenuInflater对象的inflate方法装载指定资源对应的菜单即可。

接下来将会开发一个使用XML资源定义菜单的实例,本实例将会把前面开发的菜单示例程序改为使用XML资源定义菜单。

实例:使用XML资源定义菜单

本实例包含两种菜单:选项菜单和上下文菜单,其中国选项菜单对应的XML资源文件如下。

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:title="@string/font_size"
android:showAsAction="always|withText"
android:icon="@drawable/font" >
<menu>
<!-- 定义一组单选菜单项 -->
<group android:checkableBehavior="single">
<!-- 定义多个菜单项 -->
<item android:id="@+id/font_10" android:title="@string/font_10"/>
<item android:id="@+id/font_12" android:title="@string/font_12"/>
<item android:id="@+id/font_14" android:title="@string/font_14"/>
<item android:id="@+id/font_16" android:title="@string/font_16"/>
<item android:id="@+id/font_18" android:title="@string/font_18"/>
</group>
</menu>
</item>
<!-- 定义一个普通菜单项 -->
<item android:id="@+id/plain_item"
android:showAsAction="always|withText"
android:title="@string/plain_item"></item>
<item android:title="@string/font_color"
android:showAsAction="always"
android:icon="@drawable/color">
<menu>
<!-- 定义一组普通菜单项 -->
<group>
<!-- 定义三个菜单项 -->
<item android:id="@+id/red_font"
android:title="@string/red_title"/>
<item android:id="@+id/green_font"
android:title="@string/green_title">
</item>
<item android:id="@+id/blue_font"
android:title="@string/blue_title"></item>
</group>
</menu>
</item>
</menu>

上面的菜单资源文件的<menu.../>元素里包含三个<item.../>子元素,这表明该菜单里包含三个菜单项。其中第一个、第三个都包含子菜单。

接下来再为该应用定义上下文菜单的资源文件,代码如下。

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- 定义一组单选菜单项目 -->
<group android:checkableBehavior="single">
<!-- 定义三个菜单项 -->
<item android:id="@+id/red" android:title="@string/red_title"
android:alphabeticShortcut="r"/>
<item android:id="@+id/green" android:title="@string/green_title"
android:alphabeticShortcut="g"/>
<item android:id="@+id/blue" android:title="@string/blue_title"
android:alphabeticShortcut="b"/>
</group>
</menu>

定义了上面两份菜单资源之后,接下来即可在Activity的onCreateOptionsMenu、onCreateContextMenu方法中加载这两份菜单资源。下面是该程序中加载并显示两份菜单的Java代码。

package org.crazyit.helloworld;

import android.os.Bundle;
import android.app.Activity;
import android.graphics.Color;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView; import android.widget.Toast; public class MenuResTest extends Activity { private TextView txt;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.menu_res_test);
txt=(TextView)findViewById(R.id.txt);
//为文本框注册上下文菜单
registerForContextMenu(txt);
} @Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflator=new MenuInflater(this);
//装填R.menu.my_menu对应的菜单,并添加到menu中
inflator.inflate(R.menu.my_menu, menu);
// Inflate the menu; this adds items to the action bar if it is present.
//getMenuInflater().inflate(R.menu.menu_res_test, menu);
return super.onCreateOptionsMenu(menu);
} @Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
MenuInflater inflator=new MenuInflater(this);
//装填R.menu.context对应的菜单,并添加到menu中
inflator.inflate(R.menu.context, menu);
menu.setHeaderIcon(R.drawable.tools);
menu.setHeaderTitle("选择背景色");
// TODO Auto-generated method stub
//super.onCreateContextMenu(menu, v, menuInfo);
}
//上下文菜单中,菜单项被单击时触发该方法
@Override
public boolean onContextItemSelected(MenuItem mi) {
//勾选菜单项
mi.setCheckable(true); //①
switch(mi.getItemId())
{
case R.id.red:
mi.setCheckable(true);
txt.setBackgroundColor(Color.RED);
break;
case R.id.green:
mi.setCheckable(true);
txt.setBackgroundColor(Color.GREEN);
break;
case R.id.blue:
mi.setCheckable(true);
txt.setBackgroundColor(Color.BLUE);
break;
}
return true;
// TODO Auto-generated method stub
//return super.onContextItemSelected(item);
}
//菜单项被单击后的回调方法
@Override
public boolean onOptionsItemSelected(MenuItem mi) {
if(mi.isCheckable())
{
//勾选该菜单项
mi.setCheckable(true);//②
}
//判断单击的是哪个菜单项,并有针对性地作出响应
switch(mi.getItemId())
{
case R.id.font_10:
txt.setTextSize(10*2);
break;
case R.id.font_12:
txt.setTextSize(12*2);
break;
case R.id.font_14:
txt.setTextSize(14*2);
break;
case R.id.font_16:
txt.setTextSize(16*2);
break;
case R.id.font_18:
txt.setTextSize(18*2);
break;
case R.id.red_font:
txt.setTextColor(Color.RED);
mi.setCheckable(true);
break;
case R.id.green_font:
txt.setTextColor(Color.GREEN);
mi.setCheckable(true);
break;
case R.id.blue_font:
txt.setTextColor(Color.BLUE);
mi.setCheckable(true);
break;
case R.id.plain_item:
Toast toast=Toast.makeText(MenuResTest.this, "您单击了普通菜单项",Toast.LENGTH_SHORT);
toast.show();
break; }
// TODO Auto-generated method stub
//return super.onOptionsItemSelected(mi);
return true;
} }

上面的程序中两行粗体字代码就是加载选项菜单资源、上下文菜单资源的关键代码。
  从上面的程序可以看出,如果使用XML资源文件定义菜单,就像使用布局文件来定义应用程序一样,Android应用的Java代码就会简单很多,因此可维护性更好。、

归纳起来,使用XML资源定义菜单有如下两个好处。

  • XML资源文件不仅负责定义应用界面,也负责定义菜单,这样可把所有界面相关的内容交给XML文件管理,而Java代码的功能更集中。
  • 后期更新、维护应用时,如果需要更新、维护菜单,打开、编辑XML文件即可,避免对Java文件的修改。

运行该程序的界面如下:

使用XML文件定义菜单的更多相关文章

  1. 菜单之二:使用xml文件定义菜单

    参考<疯狂android讲义>2.10节 P174,参见归档project:XmlMenuDemo.zip 一般推荐使用XML文件定义菜单. 基本步骤如下: 1.定义布局文件 为简单显示原 ...

  2. 菜单之二:使用xml文件定义菜单 分类: H1_ANDROID 2013-11-03 09:39 1038人阅读 评论(0) 收藏

    参考<疯狂android讲义>2.10节 P174,参见归档project:XmlMenuDemo.zip 一般推荐使用XML文件定义菜单. 基本步骤如下: 1.定义布局文件 为简单显示原 ...

  3. Spring Framework------>version4.3.5.RELAESE----->Reference Documentation学习心得----->使用spring framework的IoC容器功能----->方法一:使用XML文件定义beans之间的依赖注入关系

    XML-based configuration metadata(使用XML文件定义beans之间的依赖注入关系) 第一部分 编程思路概述 step1,在XML文件中定义各个bean之间的依赖关系. ...

  4. Android笔记(六十六) android中的动画——XML文件定义属性动画

    除了直接在java代码中定义动画之外,还可以使用xml文件定义动画,以便重用. 如果想要使用XML来编写动画,首先要在res目录下面新建一个animator文件夹,所有属性动画的XML文件都应该存放在 ...

  5. c# winform读取xml创建菜单

    动态创建菜单使得程序灵活性大大增加,本文根据读取xml文件中的配置菜单项来动态创建菜单,代码如下: using System; using System.Collections.Generic; us ...

  6. XML文件定义约束

    今天在做Android项目的时候,用到了XML解析,服务端返回的不是JSON,而是XML,这时候就需要我们解析XML了,当然在解析XML的时候,需要了XML文件的定义结构,任何一个文件的定义都是要遵循 ...

  7. 疯狂Android讲义 - 学习笔记(二)

    Android应用的用户界面编程 2.1 界面编程与视图(View)组件 Android应用的绝大部分UI组件放在android.widget.android.view包及其子包中,所有UI组件都继承 ...

  8. 安卓开发-使用XML菜单布局简单介绍

    使用xml布局菜单   目前为止我们都是通过硬编码来增加菜单项的,android为此提供了一种更便利的方式,就是把menu也定义为应用程序的资源,通过android对资源的本地支持,使我们可以更方便地 ...

  9. Android开发 ---代码创建选项菜单、隐藏菜单项、菜单的生命周期,菜单按钮图标设置、搜索框、xml中设置子菜单

    1.activity_main.xml 描述: 定义了一个按钮 <?xml version="1.0" encoding="utf-8"?> < ...

随机推荐

  1. 百度网盘API的操作--PCS 百度个人云存储 上传 ,下载文件

    来自http://blog.csdn.net/u014492257/article/details/39856403 另外需要所有API使用方法的请访问本人上传的资源(需要3个下载分的)链接: htt ...

  2. 自动化运维工具Ansible详细部署

    本文来源:http://sofar.blog.51cto.com/353572/1579894/ 前言 一个由 Python 编写的强大的配置管理解决方案.尽管市面上已经有很多可供选择的配置管理解决方 ...

  3. web前端性能优化指南

    web前端性能优化指南 web前端性能优化指南 概述 1. PC优化手段在Mobile侧同样适用2. 在Mobile侧我们提出三秒种渲染完成首屏指标3. 基于第二点,首屏加载3秒完成或使用Loadin ...

  4. webpack.config.js 参数简单了解

    webpack.config.js文件通常放在项目的根目录中,它本身也是一个标准的Commonjs规范的模块. var webpack = require('webpack'); module.exp ...

  5. CodeForces 617D Polyline

    无脑暴力判断. #include<cstdio> #include<cstring> #include<vector> #include<cmath> ...

  6. Linux建立信任主机

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1.先在本机上面装一个sshpass 的安装包 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2.ssh-ke ...

  7. 使用LIBUSB实现和自定义通讯设备通讯--MFC代码在末尾

    LIBUSB是一款简单好用的USB通讯开发库,一般HID设备用该库通讯能大大降低开发周期,使用如下,首先需要为设备安装驱动 在libusb的bin目录下有一个inf_wirzed.exe的文件,该文件 ...

  8. 《javascript语言精粹》——第3章对象

    第三章:对象: 属性名字:可以是包括空字符串在内的任意字符串: 属性值:是除undefined值之外的任何值; [1].对象字面量: var obj={}; //空对象 var obj = new O ...

  9. BMP085气压传感器驱动

    BMP085是新一代的小封装气压传感器,主要用于气压温度检测,在四轴飞行器上可以用作定高检测,该传感器属于IIC总线接口,依然沿用标准IIC驱动程序 使用该传感器需要注意的是我们不能直接读出转换好的二 ...

  10. Qt下libusb-win32的使用(转)

    源:Qt下libusb-win32的使用(一)打印设备描述符 主要是在前一篇的基础上,学习libusb-win32的API使用.程序很简单,就是打印指定USB设备的设备描述符(当然其他描述符也是可以的 ...