Android开发06—菜单与对话框(上)
1. 菜单
1) 选项菜单和子菜单
当Activity在前台工作的时候,按下menu将会弹出相应的选项菜单。这个功能是需要开发人员编成实现的,如果在程序中没有此功能,那么程序运行时按下手机的menu键将不会有反映。
对于有图标的选项菜单,每次最多能显示6个,当多于6个时,将只显示前5个和一个拓展菜单选项。
在Android中通过回调方法来创建菜单并处理菜单按下的事件。
开发选项菜单主要用到Menu,MenuItem及SubMenu
实例:接受用户在菜单中的选项并输出到文本框控件中
main.xml:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_height="fill_parent" android:layout_width="fill_parent" android:id="@+id/linearLayout1"> <ScrollView android:layout_width="fill_parent" android:layout_height="fill_parent" android:id="@+id/scrollView1"> <EditText android:layout_width="fill_parent" android:layout_height="fill_parent" android:id="@+id/editText1" android:editable="false" android:cursorVisible="false" android:text="@string/label"></EditText> </ScrollView> </LinearLayout>Activity:
package qijia.si;import android.app.Activity;import android.app.TabActivity;import android.os.Bundle;import android.view.LayoutInflater;import android.view.Menu;import android.view.MenuItem;import android.view.MenuItem.OnMenuItemClickListener;import android.view.SubMenu;import android.view.View;import android.view.ViewGroup;import android.widget.AdapterView;import android.widget.AdapterView.OnItemClickListener;import android.widget.BaseAdapter;import android.widget.EditText;import android.widget.Gallery;import android.widget.ImageView;import android.widget.ProgressBar;import android.widget.RatingBar;import android.widget.TabHost;public class JavaTest extends Activity { /** Called when the activity is first created. */ 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 public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } public boolean onCreateOptionsMenu(Menu menu){ //初始化菜单通过此函数实现 SubMenu subMenuGender = menu.addSubMenu(MAIN_GROUP,MENU_GENDER,0,R.string.gender); subMenuGender.setIcon(R.drawable.gender); subMenuGender.setHeaderIcon(R.drawable.gender); male = subMenuGender.add(GENDER_GROUP,MENU_GENDER_MALE,0,R.string.male); male.setChecked(true); subMenuGender.add(GENDER_GROUP,MENU_GENDER_FEMALE,0,R.string.female); subMenuGender.setGroupCheckable(GENDER_GROUP, true, true); SubMenu subMenuHobby = menu.addSubMenu(MAIN_GROUP,MENU_HOBBY,0,R.string.hobby); subMenuHobby.setIcon(R.drawable.hobby); miaHobby[0] = subMenuHobby.add(HOBBY_GROUP,MENU_HOBBY1,0,R.string.hobby1); miaHobby[1] = subMenuHobby.add(HOBBY_GROUP,MENU_HOBBY2,0,R.string.hobby2); miaHobby[2] = subMenuHobby.add(HOBBY_GROUP,MENU_HOBBY3,0,R.string.hobby3); miaHobby[0].setCheckable(true); miaHobby[1].setCheckable(true); miaHobby[2].setCheckable(true); MenuItem ok = menu.add(GENDER_GROUP+2,MENU_OK,0,R.string.ok); OnMenuItemClickListener lsn = new OnMenuItemClickListener(){ public boolean onMenuItemClick(MenuItem item) { // TODO Auto-generated method stub appendStateStr(); return true; } }; ok.setOnMenuItemClickListener(lsn); ok.setAlphabeticShortcut('o'); return true; } public boolean onOptionsItemSelected(MenuItem mi){ switch(mi.getItemId()){ case MENU_GENDER_MALE: case MENU_GENDER_FEMALE: mi.setChecked(true); appendStateStr(); break; case MENU_HOBBY1: case MENU_HOBBY2: case MENU_HOBBY3: mi.setChecked(!mi.isChecked()); appendStateStr(); break; } return true; } public void appendStateStr(){ String result = "您选择的性别为:"; if(male.isChecked()){ result = result +"男"; }else{ 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)+"。\n"; } else{ result = result+"。\n"; } EditText et = (EditText) JavaTest.this.findViewById(R.id.editText1); et.append(result); }}2. 上下文菜单
ContextMenu继承自Menu。上下文菜单不同于选项菜单,选项菜单服务于Activity,而上下文菜单是注册到某个View对象上的。如果一个View对象注册了上下文菜单,用户可以通过长按该View对象以呼叫上下文菜单。
上下文菜单不支持快捷键,也不能附带图标,但是可以为上下文菜单的标题指定图标。
用法实例:
main.xml:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_height="fill_parent" android:orientation="vertical" android:layout_width="fill_parent" android:id="@+id/linearLayout1"> <EditText android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/editText1" android:text="@string/et1"></EditText> <EditText android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/editText2" android:text="@string/et2"></EditText> </LinearLayout>
Acticity:
package qijia.si;import android.app.Activity;import android.os.Bundle;import android.view.ContextMenu;import android.view.MenuItem;import android.view.View;import android.widget.EditText;public class ContextMenuDemo extends Activity { //定义菜单编号 final int MENU1 = 1; final int MENU2 = 2; final int MENU3 = 3; final int MENU4 = 4; final int MENU5 = 5; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); //注册上下文菜单 this.registerForContextMenu(findViewById(R.id.editText1)); this.registerForContextMenu(findViewById(R.id.editText2)); } //此方法在每次调用上下文菜单时都会被调用一次 public void onCreateContextMenu (ContextMenu menu,View v, ContextMenu.ContextMenuInfo menuInfo){ //为上下文设置标题图标 menu.setHeaderIcon(R.drawable.header); //若是第一文本框 if(v == findViewById(R.id.editText1)){ //为上下文菜单添加菜单选项 menu.add(0,MENU1,0,R.string.mi1); menu.add(0,MENU2,0,R.string.mi2); menu.add(0,MENU3,0,R.string.mi3); }else if(v == findViewById(R.id.editText2)){ menu.add(0,MENU4,0,R.string.mi4); menu.add(0,MENU5,0,R.string.mi5); } } //菜单选项选中状态变化后的回调方法 public boolean onContextItemSelected(MenuItem mi){ //判断被选中的MenuItem switch(mi.getItemId()){ case MENU1: case MENU2: case MENU3: EditText et1 = (EditText)this.findViewById(R.id.editText1); et1.append("\n"+mi.getTitle()+" 被按下"); break; case MENU4: case MENU5: EditText et2 = (EditText)this.findViewById(R.id.editText2); et2.append("\n"+mi.getTitle()+" 被按下"); break; } return true; } }3. 对话框
对话框是Activity运行时显示的小窗口,当显示对话框时,当前Activity失去焦点而由对话框负责所有的人机交互。一般来说,对话框用于提示消息或弹出一个与程序主进程直接相关的小程序。
Android平台下主要有以下几种对话框:
1) 提示对话框 AlertDialog
AlertDialog对话框可以包含若干按钮和一些可选的单选按钮或复选框。
2) 进度对话框
ProgressDialog可以显示进度轮或进度条,由于ProgressDialog继承自AlertDialog,所以其也可以添加按钮。
3) 日期选择对话框DatePickerDialog
4) 时间选择对话框TimePickerDialog
对话框是作为Activity的一部分被创建和显示的,在程序中通过开发回调方法onCreateDialog来完成对话框的创建,该方法需要传入代表对话框id参数。如果需要显示对话框,则调用showDialog方法传入对话框id来显示指定的对话框。
当对话框第一次被显示时,Android会调用onCreateDialog方法来创建对话框实例,之后将不再重复创建该实例。同时,每次对话框再被显示之前都会调用onPrepareDialog方法,如果补充些该方法,那么每次显示的对话框将是最初创建的那个。
关闭对话框可以调用Dialog类的dismiss方法来实现,但是要注意这种方法不会让对话框彻底消失,如果要对话框被关闭后彻底消失,要调用removeDialog方法并传入Dialog的id。
下面通过普通对话框的例子来说明如何使用:
main.xml:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/linearLayout1" android:layout_height="fill_parent" android:orientation="vertical" android:layout_width="fill_parent"> <EditText android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/editText1" android:text="@string/blank" android:editable="false" android:cursorVisible="false"></EditText> <Button android:id="@+id/button1" android:layout_height="wrap_content" android:text="@string/btn" android:layout_width="fill_parent"></Button> </LinearLayout>
Activity:
package qijia.si;import android.app.Activity;import android.app.AlertDialog;import android.app.AlertDialog.Builder;import android.app.Dialog;import android.content.DialogInterface;import android.content.DialogInterface.OnClickListener;import android.os.Bundle;import android.view.ContextMenu;import android.view.MenuItem;import android.view.View;import android.widget.Button;import android.widget.EditText;public class ContextMenuDemo extends Activity { //普通对话框id final int COMMON_DIALOG = 1; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); //获取Button对象 Button btn = (Button)findViewById(R.id.button1); //为Button设置监听器 btn.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { // TODO Auto-generated method stub showDialog(COMMON_DIALOG); } }); } //重写onCreateDialog方法 public Dialog onCreateDialog(int id){ //声明一个dialog对象用于返回 Dialog dialog = null; switch(id){ case COMMON_DIALOG: Builder b = new AlertDialog.Builder(this); //设置对话框图标 b.setIcon(R.drawable.header); b.setTitle(R.string.btn); b.setMessage(R.string.dialog_msg); //添加按钮 b.setPositiveButton(R.string.ok, new OnClickListener(){ public void onClick(DialogInterface dialog, int which) { // TODO Auto-generated method stub EditText et = (EditText)findViewById(R.id.editText1); et.setText(R.string.dialog_msg); } }); dialog = b.create(); break; default: break; } return dialog; } }