android平台提供的菜单大体分为三类:选项菜单,上下文菜单和子菜单。
本程序实现的功能是选择自己的性别和爱好,当运行该程序时,进入主界面,单击模拟器上的Menu按钮,在模拟器的下方会弹出三个选项,单击"性别"选项,弹出性别对话框,单击菜单菜单中的"爱好"选项弹出爱好对话框。
在该软件中主要使用的是SubMenu类,通过该类创建菜单选项按钮,创建菜单项目的编号,为其设定级别,随后在重写的onCreateOptionsMenu方法中完成选项菜单的设置。
重写单选或复选菜单项选中状态变化后的回调方法onOptionsItemSelected,完成所选信息的更新。
运行效果:
首先介绍布局文件的设计与实现:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ScrollView
android:id="@+id/sl"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<EditText
android:id="@+id/et"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="false"
android:text="你选的选择为:"/>
</ScrollView>
</LinearLayout>
scrollView标签中放了一个EditText控件,可以实现EditText当内容太多实现上下滚动。
接下来介绍主要功能代码;
package com.example.menuchoice;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MenuItem.OnMenuItemClickListener;
import android.view.SubMenu;
import android.widget.EditText;
public class MainActivity extends ActionBarActivity {
final int MENU_GENDER_MALE = 0;
final int MENU_GENDER_FEMALE = 1;
final int MENU_HOBBY1 = 2;
final int MENU_HOBBY2 = 3;
final int MENU_HOBBY3 = 4;
final int MENU_OK = 5;
final int MENU_GENDER = 6;
final int MENU_HOBBY = 7;
final int GENDER_GROUP = 0;
final int HOBBY_GROUP = 1;
final int MAIN_GROUP = 2;
MenuItem[] miaHobby = new MenuItem[3];
MenuItem male = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
//** 为EditText添加状态信息
public void appendStateStr(){
String result = "你选择的性别为:";
//** 若为选中状态
if(male.isChecked()){
result = result+"男";
}
else
{
result = result+"女";
}
String hobbyStr = "";
for(MenuItem mi:miaHobby){
if(mi.isChecked()){
hobbyStr = hobbyStr+mi.getTitle()+"、";
}
}
if(hobbyStr.length()>0){
result = result+",你的爱好为:"+hobbyStr.substring(0, hobbyStr.length()-1)+"。";
}
else
{
result = result+"。\n";
}
EditText et = (EditText) MainActivity.this.findViewById(R.id.et);
et.setText(result);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
//** 性别单选菜单项组
SubMenu subMenuGender = menu.addSubMenu(MAIN_GROUP,MENU_GENDER,0,"性别");
subMenuGender.setIcon(R.drawable.a);
male = subMenuGender.add(GENDER_GROUP, MENU_GENDER_MALE, 0, "男性");
male.setChecked(true);
subMenuGender.add(GENDER_GROUP,MENU_GENDER_FEMALE,0,"女性");
//** 设置GENDER_GROUP组是可选择的,互斥的
subMenuGender.setGroupCheckable(GENDER_GROUP, true, true);
//** 爱好复选菜单项组
SubMenu subMenuHobby = menu.addSubMenu(MAIN_GROUP, MENU_HOBBY, 0,"爱好");
subMenuHobby.setIcon(R.drawable.a);
miaHobby[0] = subMenuHobby.add(HOBBY_GROUP,MENU_HOBBY1,0,"游泳");
miaHobby[1] = subMenuHobby.add(HOBBY_GROUP,MENU_HOBBY2,0,"唱歌");
miaHobby[2] = subMenuHobby.add(HOBBY_GROUP,MENU_HOBBY3,0,"写java程序");
//** 设置菜单项为复选菜单项
miaHobby[0].setCheckable(true);
miaHobby[1].setCheckable(true);
miaHobby[2].setCheckable(true);
MenuItem ok = menu.add(GENDER_GROUP+2,MENU_OK,0,"确定");
OnMenuItemClickListener lsn = new OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem arg0) {
appendStateStr();
return true;
}
};
ok.setOnMenuItemClickListener(lsn);
ok.setAlphabeticShortcut('o');
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case MENU_GENDER_MALE:
case MENU_GENDER_FEMALE:
item.setChecked(true);
appendStateStr();
break;
case MENU_HOBBY1:
case MENU_HOBBY2:
case MENU_HOBBY3:
item.setChecked(!item.isChecked());
appendStateStr();
}
return true;
}
}
创建子菜单的步骤:
(1) 覆盖Activity的onCreateOptionsMenu()方法,调用Menu的addSubMenu()方法来添加子菜单
(2) 调用SubMenu的add()方法,添加子菜单项
(3) 覆盖onOptionsItemSelected(MenuItem item)方法,响应子菜单的单击事件
这样就可以实现子菜单的添加。
上边介绍的是选项菜单,接下来介绍上下文菜单。上下文菜单与选项菜单不同,选项菜单是为整个activity服务的,而上下文菜单是注册到某个View的。
上下文菜单默认情况下通过长按(约2秒)相应View以调出上下文菜单。单击弹出对话框中的选项时则在相应的文本框中显示所单击的选项。
运行效果如下:
当一个View注册了上下文菜单后,长按2秒后即可打开包含自定义选项的对话框,需要重写菜单项选择状态变化后的回调方法onCreateContextMenu和菜单项选中状态变化后的回调方法onContextItemSelected.
首先给出布局文件的代码:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<EditText
android:id="@+id/et1"
android:text="第一个文本框"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<EditText
android:text="第二个文本框"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/et2"
/>
</LinearLayout>
在布局文件中添加了两个EditText控件。竖直放置。
接下介绍主功能代码:
package com.example.contextmenu;
import android.support.v7.app.ActionBarActivity;
import android.view.ContextMenu;
import android.view.MenuItem;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.widget.EditText;
import android.os.Bundle;
public class MainActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.registerForContextMenu(findViewById(R.id.et1));
this.registerForContextMenu(findViewById(R.id.et2));
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v,ContextMenuInfo menuInfo) {
if(v == findViewById(R.id.et1)){
menu.addSubMenu(0, 1, 0, "菜单项1");
menu.addSubMenu(0, 2, 0, "菜单项2");
menu.addSubMenu(0, 3, 0, "菜单项3");
}
else if(v == findViewById(R.id.et2))
{
menu.addSubMenu(0, 4, 0, "菜单项4");
menu.addSubMenu(0, 5, 0, "菜单项5");
}
}
@Override
public boolean onContextItemSelected(MenuItem item) {
switch (item.getItemId()) {
case 1:
case 2:
case 3:
EditText et = (EditText) this.findViewById(R.id.et1);
et.append("\n"+item.getTitle()+"被按下");
break;
case 4:
case 5:
EditText et2 = (EditText) this.findViewById(R.id.et2);
et2.append("\n"+item.getTitle()+"被按下");
break;
}
return true;
}
}
首先为两个控件注册上下文菜单,然后根据传入的View添加菜单。通过重写onContextItemSelected()方法,当菜单项选择状态变化后回调方法为EditText添加数据。