Android主要提供了两周创建菜单的方式,一种是在Java代码中创建(即调用Menu、SubMenu类中的方法实现菜单/子菜单/菜单项的创建);另外一种就是使用XML资源文件来定义。对于第一种方法,我们在上一篇文章中已经有了很详细的介绍,但是在Java代码中定义菜单、菜单项而导致程序代码非常臃肿且不易调试阅读。本文将着重介绍使用XML资源文件来定义菜单的构成(
即利用XML资源文件来描述一个菜单),使用这种方式只需要为每个菜单或菜单项分配一个ID,以便在事件响应方法中通过判定ID实现对应的组件响应(相当于第一种方法中的标识)。特点:有利于扩展,可维护性降低。
一、Menu中XML资源文件构成
菜单资源文件通常应放在/res/menu目录下,菜单的XML资源文件,主要有三个重要的元素:<menu../> <item../><group../>,其中菜单资源的根元素通常是<menu../>元素,并且<menu../>元素无须指定任何属性。
下面我们着重介绍三个元素的作用:
1.<menu../>元素:用于定义一个菜单/子菜单。<menu../>元素主要有两个作用,一是整个菜单资源的根元素,将相当于布局文件中的<LinearLayout../>;二是,当Menu菜单包含子菜单时,<menu../>元素是该子菜单的根元素。
举例:创建一个菜单项
<menu>
<item../>
</menu>
2.<item../>元素:用于定义一个菜单项/子菜单项。有如下常用属性。
(1)android:id:为菜单项指定一个唯一的标识,用于事件响应判定;
(2)android:title:设置(子)菜单项标题;
(3)android:icon:设置菜单项图标;
(4)android:checkable:设置该菜单项是否可选
(5)android:checked:设置该菜单项是否已经选中
(6)android:visible:设置菜单项是否可见
(7)android:enable:设置菜单项是否可用
(8)android:alphabeticShortcut/numbericShortcut:为菜单项指定字符/数字快捷键
3.<group../>元素:用于创建一组菜单项,在创建一个子菜单时使用。常用属性:
android:checkableBehavior:设置所属子菜单项是单选还是多选(值为"single"等)
举例:创建一个子菜单,并且包含三个子菜单项。
<menu> //菜单
<item...> //一个菜单项
<menu> //子菜单
<group android:checkableBehavior=“single”>
<item../> //子菜单项1
<item../> //子菜单项2
<item../> //子菜单项3
</menu>
</item>
</menu>
二、Menu菜单开发基本思路
1.创建XML资源文件(在res/menu/menu.xml),为每个菜单项或子菜单项定义一个ID---构建菜单外观;
2.重写Activity的onCreateOptionsMenu(Menu menu)(适用Menu菜单)或者onCreateContextMenu(ContextMenu menu,View source,ContextMenuInfo menuIfo)(适用上下文菜单)的方法,在该方法里调用Menu对象的方法来添加菜单项或者子菜单;
3.在onCreateOptionsMenu(Menu menu)或者onCreateContextMenu(ContextMenu menu,View source,ContextMenuInfo menuIfo)中调用
MenuInflater的
infate(R.menu.*,menu)方法,装填XML资源文件对应的菜单(如R.menu.menu.xml),并添加到
menu菜单或者上下文菜单中;
- MenuInflater inflator=new MenuInflater(this); //实例化一个MenuInflater对象
- inflator.inflate(R.menu.menu, menu); //将xml对应的菜单资源添加到menu中
2.重写Activity的onCreateOptionsMenu(Menu menu)(适用Menu菜单)或者onContextItemSelected(MenuItem mi)(适用于上下文菜单)的方法,通过菜单项标识符(
菜单项ID)来判定该响应哪一个菜单项。
三、源代码
由于布局文件只有一个文本框,故无需给出。
1.menu菜单XML资源文件:res/menu/menu.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: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:title="@string/palin_item">
- </item>
- <!-- 第三个菜单项:字体颜色-->
- <item
- android:title="@string/font_color"
- android:icon="@drawable/color">
- <!-- 定义一组单选菜单项 ,然后定义一组菜单选项-->
- <menu>
- <group>
- <item
- android:id="@+id/red_font"
- android:title="@string/red_title"/>
- <item
- android:id="@+id/blue_font"
- android:title="@string/blue_title"/>
- <item
- android:id="@+id/green_font"
- android:title="@string/blue_title"/>
- </group>
- </menu>
- </item>
- </menu>
2.文本框上下文菜单:res/menu/context.xml
- <?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/blue"
- android:title="@string/blue_title"
- android:alphabeticShortcut="b"/>
- <item
- android:id="@+id/green"
- android:title="@string/green_title"
- android:alphabeticShortcut="g"/>
- </group>
- </menu>
3.MainActivity.java源文件
- package com.android.android_menu_xml;
- //import android.support.v7.app.ActionBarActivity;
- import android.app.Activity;
- import android.graphics.Color;
- import android.os.Bundle;
- import android.view.ContextMenu;
- 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 MainActivity extends Activity {
- private TextView text;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- //获取文本视图控件,并向其注册一个上下文才菜单
- setContentView(R.layout.main);
- text=(TextView)findViewById(R.id.txt);
- registerForContextMenu(text);
- }
- //1.创建Menu菜单 ,将menu.xml资源添加到menu中
- public boolean onCreateOptionsMenu(Menu menu)
- {
- MenuInflater inflator=new MenuInflater(this); //实例化一个MenuInflater对象
- inflator.inflate(R.menu.menu, menu); //将xml对应的菜单资源添加到menu中
- return super.onCreateOptionsMenu(menu);
- }
- //2.创建上下文才菜单,将context.xml资源添加到contextmenu中
- public void onCreateContextMenu(ContextMenu menu,View source,ContextMenu.ContextMenuInfo menuInfo)
- {
- MenuInflater inflator=new MenuInflater(this); //实例化一个MenuInflater对象
- inflator.inflate(R.menu.context, menu); //将xml对应的菜单资源添加到menu中
- menu.setHeaderIcon(R.drawable.color); //设置上下文菜单图标
- menu.setHeaderTitle("请选择背景颜色"); //设置上下文菜单标题
- }
- //3.响应上下文菜单项
- public boolean onContextItemSelected(MenuItem menutem)
- {
- menutem.setChecked(true); //勾选该菜单选项
- switch(menutem.getItemId()) //获取触发的菜单项id,响应
- {
- case R.id.red: //调用TextView的setBackgroundColor方法设置背景颜色
- menutem.setChecked(true);
- text.setBackgroundColor(Color.RED);
- break;
- case R.id.blue:
- menutem.setChecked(true);
- text.setBackgroundColor(Color.BLUE);
- break;
- case R.id.green:
- menutem.setChecked(true);
- text.setBackgroundColor(Color.GREEN);
- break;
- }
- return true;
- }
- //4.响应Menu菜单项
- public boolean onOptionsItemSeleted(MenuItem mi)
- {
- if(mi.isCheckable())
- {
- mi.setChecked(true);
- }
- switch(mi.getItemId()) //获取菜单项Id,并做出响应
- {
- //设置字体大小
- case R.id.font_10:
- text.setTextSize(10*2);
- break;
- case R.id.font_12:
- text.setTextSize(12*2);
- break;
- case R.id.font_14:
- text.setTextSize(14*2);
- break;
- case R.id.font_16:
- text.setTextSize(16*2);
- break;
- case R.id.red:
- text.setTextSize(18*2);
- break;
- //设置字体颜色
- case R.id.red_font:
- mi.setChecked(true);
- text.setTextColor(Color.RED);
- break;
- case R.id.blue_font:
- text.setTextColor(Color.BLUE);
- mi.setChecked(true);
- break;
- case R.id.green_font:
- text.setTextColor(Color.GREEN);
- mi.setChecked(true);
- break;
- //设置普通菜单响应
- case R.id.plain_item:
- Toast toast=Toast.makeText(MainActivity.this, "您单击了普通菜单", Toast.LENGTH_SHORT);
- toast.show();
- break;
- }
- return super.onOptionsItemSelected(mi);
- }
- }
效果如下: