第5章
对话框、菜单和状态栏通知   
作为用户交互的重要工具和手段,对话框、菜单和状态栏通知在UI设计中发挥着重
要的作用。对话框是一种浮于Activity之上的界面元素,一般用于给出提示信息或弹出
一个与主进程直接相关的子程序;菜单能够在不占用界面空间的前提下为应用程序提供
相应的功能和界面;状态栏通知是一种具有全局效果的提醒机制,不会打断用户当前的操
作。本章将介绍这些界面元素的使用方法。

5.对话框
1 

在Android中,对话框是提示用户做出决定或输入额外信息的小窗口。对话框不会填
充屏幕,通常用于需要用户采取行动才能继续执行的情形。当显示对话框时,当前Activity
失去焦点而由对话框负责所有的交互。常用的对话框有提示对话框(AlertDialog)、日期选
择对话框(DatePickerDialog)、时间选择对话框(TimePickerDialog)等,其中AlertDialog是最
常用的对话框。这些对话框都是andodaDilg的子类。

ri.pp.ao

5.1.1 
提示对话框
AlertDialog是一个消息提示对话框,能构造默认的3个按钮,分别用于肯定、否定和
中立。创建AlertDialog的主要步骤如下。

步骤1:获得AlertDialog的静态内部类Builder对象,并由该对象来创建对话框。

步骤2:通过Builder对象设置对话框的标题、文字等属性。表5-1列出了Builder对
象的部分常用方法。

表5-
1 
Builder对象的部分常用方法

方法名

setIcon() 
setTitle() 
setMesage() 
setItems() 

说明

设置显示在对话框标题左侧的图标
设置对话框的标题
设置对话框的提示文字
设置对话框显示一个列表


续表
1 32 Android软件开发教程(第3版·微课版) 
方 法 名说 明
setSingleChoiceItems() 设置对话框显示一个单选的选项列表
setMultiChoiceItems() 设置对话框显示一系列的复选框
setPositiveButton() 使肯定按钮可见并为其设置Click事件监听器
setNegativeButton() 使否定按钮可见并为其设置Click事件监听器
setNeutralButton() 使中立按钮可见并为其设置Click事件监听器
setView() 设置一个自定义的View 对象作为对话框的显示内容。调用该方法可以在对
话框中显示一个布局或UI对象
setCancelable() 设置对话框是否能被取消
create() 创建AlertDialog对象,该方法的返回值为AlertDialog对象
show() 创建AlertDialog对象并显示对话框,该方法的返回值为AlertDialog对象 
步骤3:设置对话框的按钮以及点击按钮的事件响应处理程序。
对话框中可以有肯定、否定和中立3个按钮。一般用户使用肯定按钮来接受并继
续执行操作,如确定操作;使用否定按钮来取消操作;中立按钮则用于用户不想继续执
行操作,但也未必想要取消操作的情况,如“稍后提醒我”的操作。生成器Builder负责
设置对话框上的按钮,并为按钮注册OnClickListener监听器。OnClickListener在
android.content.DialogInterface包中,事件处理时回调onClick()方法。无论用户点击哪
个按钮,对话框都会关闭,并导致接口中的onClick()方法被调用。onClick()方法的定
义如下: 
abstract void onClick(DialogInterface dialog, int which) 
其中,参数dialog就是当前要关闭的对话框,参数which是用户点击的按钮,其取值可以
是DialogInterface.BUTTON_NEGATIVE、DialogInterface.BUTTON_NEUTRAL 或
DialogInterface.BUTTON_POSITIVE。
步骤4:调用Builder对象的show()方法创建并显示对话框。或者调用Builder对象
的create()方法创建AlertDialog对象,再调用AlertDialog对象的show()方法显示对
话框。如
果不希望用户点击设备的“返回”按钮或在对话框外部点击使对话框消失,而是要
求用户必须点击对话框中的按钮,可以通过调用AlertDialog对象的setCancelable(false) 
方法来进行设置。
1.简单提示对话框
简单提示对话框仅包括文字标题、标题左侧的图标、文字提示信息、按钮等基本元素。

第5章 对话框、菜单和状态栏通知1 33 
【例5-1】 示例工程Demo_05_AlertDialog演示了AlertDialog对话框的用法。
在主界面中有“弹出AlertDialog对话框”按钮,点击该按钮后弹出AlertDialog,如
图5-1所示,主要代码如代码段5-1所示。
图5-1 AlertDialog提示 
代码段5-1 创建简单的AlertDialog 
btnStart.setOnClickListener(new View.OnClickListener() { 
public void onClick(View v) { 
AlertDialog.Builder myDialog= new AlertDialog.Builder(MainActivity. 
this); //创建AlertDialog.Builder 对象 
myDialog.setIcon(R.mipmap.ic_launcher); // 设 置图标 
myDialog.setTitle("提示"); / /设置标题 
myDialog.setMessage("这是一个AlertDialog!"); //设置消息内容 
myDialog.setNegativeButton("取消", null); // 否 定 按钮 
myDialog.setNeutralButton("稍后提醒我", null); / /中 立 按钮 
myDialog.setPositiveButton("确定", new DialogInterface. 
OnClickListener() { //肯定按钮 
@Override 
public void onClick(DialogInterface dialog, int which) { 
Toast.makeText(getApplicationContext(), "您点击了“确定”按
钮!", Toast.LENGTH_LONG).show(); 
} 
}); 
myDialog.show(); //显示对话框 
} 
}); 
2.其他风格的提示对话框
除了按钮对话框,还可以创建列表对话框、单选对话框、多选对话框。通过调用
setItems()方法,可以在AlertDialog中添加列表项;通过调用setSingleChoiceItems()/ 
setMultiChoiceItems()方法,可以在AlertDialog中添加单选或多选列表。
AlertDialog

1 34 Android软件开发教程(第3版·微课版) 
【例5-2】 示例工程Demo_05_ListDialog演示了列表对话框的用法。
在Activity中点击“弹出列表对话框”按钮后,弹出AlertDialog,运行效果如图5-2所
示。当在对话框中选择了一项之后,Activity中TextView的显示内容随之更新。
图5-2 列表对话框
首先在values下arrays.xml文件中定义字符串数组,内容如代码段5-2所示。创建
列表对话框的主要代码如代码段5-3所示。 
代码段5-2 定义字符串数组
<? xml version="1.0" encoding="utf-8"? > 
<resources> 
<string-array name="favor"> 
<item>音乐</item> 
<item>体育</item> 
<item>美术</item> 
</string-array> 
</resources> 
代码段5-3 创建列表对话框
btnStart.setOnClickListener(new View.OnClickListener() { 
public void onClick(View v) { 
AlertDialog.Builder myDialog= new AlertDialog.Builder(MainActivity. 
this); 
myDialog.setTitle("列表对话框,请选择") //设置对话框的标题 
.setItems( //用字符串数组设置列表中的各个属性 
R.array.favor, new DialogInterface.OnClickListener() { 
//设置监听器 
public void onClick(DialogInterface dialog, int which) { 
TextView message=(TextView) findViewById(R.id.text1); 
message.setText("您选择了:" + getResources(). 
getStringArray(R.array.favor)[which]);

第5章 对话框、菜单和状态栏通知1 35 
} 
}) 
.setNeutralButton("取消", new DialogInterface.OnClickListener() { 
@Override 
public void onClick(DialogInterface dialogInterface, int i) { 
Toast.makeText(getApplicationContext(), "您取消了选
择", Toast.LENGTH_SHORT).show(); 
} 
}) 
.show(); 
} 
}); 
【例5-3】 示例工程Demo_05_RadioButtonDialog演示了单选对话框的用法。
本例使用与例5-2示例工程中相同的数组资源,当点击“弹出单选对话框”按钮后,弹
出AlertDialog,运行效果如图5-3所示。创建单选对话框的主要代码如代码段5-4所示。
图5-3 单选对话框 
代码段5-4 创建单选对话框
btnStart.setOnClickListener(new View.OnClickListener() { 
public void onClick(View v) { 
AlertDialog.Builder myDialog= new AlertDialog.Builder(MainActivity. 
this); 
myDialog.setTitle("单选对话框,请选择") //设置对话框的标题 
.setSingleChoiceItems( // 设置单选按钮选项 
R.array.favor, selectedItem, new DialogInterface. 
OnClickListener() { 
public void onClick(DialogInterface dialog, int which) { 
selectedItem=which; 
}

1 36 Android软件开发教程(第3版·微课版) 
}); 
myDialog.setPositiveButton("确定", new DialogInterface.OnClickListener() { 
@Override 
public void onClick(DialogInterface dialogInterface, int i) { 
TextView message=(TextView) findViewById(R.id.text1); 
message.setText("您选择了:"+getResources(). 
getStringArray(R.array.favor)[selectedItem]); 
} 
}); 
myDialog.setNegativeButton("取消", new DialogInterface.OnClickListener() { 
@Override 
public void onClick(DialogInterface dialogInterface, int i) { 
Toast.makeText(getApplicationContext(), "您取消了选择", Toast 
.LENGTH_SHORT).show(); 
} 
}); 
myDialog.show(); 
} 
}); 
3.具有复杂界面的提示对话框
通过调用AlertDialog.Builder对象的setView()方法,可以将自定义的View 或布局
添加至AlertDialog。这样就可以实现在对话框中显示较复杂的内容。在默认情况下,自
定义布局会填充整个对话框。
【例5-4】 示例工程Demo_05_ViewDialog演示了如何将自定义的View 作为其内
容显示在对话框中,该程序通过点击“弹出登录对话框”按钮来弹出一个用来显示登录界
面的对话框。
为了实现上述功能,需要为对话框设计相应的布局。在res\layout下创建一个XML 
布局文件dialog_view.xml,布局的主要内容是提示文字及对应的文本输入框,分别用于
输入用户名和密码,其主要代码如代码段5-5所示。对话框中的“登录”“注册”“退出”按
钮不需要在布局文件中设定,而是在Builder被实例化后通过调用setPositiveButton()、
setNegativeButton()和setNeutralButton()方法来添加,并在其中分别设定3个按钮对应
的事件处理程序。 
代码段5-5 dialog_view.xml 布局文件
<? xml version="1.0" encoding="utf-8"? > 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:orientation="vertical" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
具有复杂界
面的提示对
话框

第5章 对话框、菜单和状态栏通知1 37 
android:padding="24dp" > 
<TextView 
android:layout_height="wrap_content" 
android:layout_width="wrap_content" 
android:textSize="18sp" 
android:text="用户名:" /> 
<EditText 
android:id="@+id/ed_username" 
android:layout_height="wrap_content" 
android:layout_width="match_parent"/> 
<TextView 
android:layout_height="wrap_content" 
android:layout_width="wrap_content" 
android:layout_marginTop="24dp" 
android:textSize="18sp" 
android:text="密码:"/> 
<EditText 
android:id="@+id/ed_password" 
android:layout_height="wrap_content" 
android:layout_width="match_parent" 
android:inputType="textPassword"/> 
</LinearLayout> 
示例工程中,点击“弹出登录对话框”按钮后弹出对话框,如图5-4所示。
图5-4 具有复杂界面的提示对话框
如果主界面中按钮被点击,则定义一个LayoutInflater类的实例。LayoutInflater类
的作用类似于findViewById(),不同点是LayoutInflater是用来引入Layout下的XML 
布局文件并且实例化,而findViewById()是引入XML 文件中定义的具体UI对象(如

1 38 Android软件开发教程(第3版·微课版) 
Button、TextView等)。这里通过调用LayoutInflater实例的inflate()方法引入XML布
局文件dialog_view.xml,然后通过调用Builder对象的setView(View)方法,在对话框中
加载这个布局文件。创建对话框的主要代码如代码段5-6所示。 
代码段5-6 定义对话框及其按钮功能
btnStart.setOnClickListener(new View.OnClickListener() { 
public void onClick(View v) { 
LayoutInflater dialogInflater=LayoutInflater.from(MainActivity.this); 
final View myViewOnDialog=dialogInflater.inflate(R.layout.dialog_ 
view, null); //引入布局 
AlertDialog.Builder myDialogInstance=new AlertDialog.Builder 
(MainActivity.this) 
.setIcon(R.mipmap.ic_launcher) //对话框的标题图标 
.setTitle("用户登录") 
.setView(myViewOnDialog) //参数是上面定义的View 实例
//名,显示dialog_view 布局 
.setPositiveButton("登录", new DialogInterface.OnClickListener() { 
//肯定按钮 
public void onClick(DialogInterface dialog, int whichButton) { 
//监听点击事件 
EditText editText=(EditText)myViewOnDialog. 
findViewById(R.id.ed_username); 
Toast.makeText(getApplicationContext(), "您的用户名是"+ 
editText.getText(), Toast.LENGTH_LONG).show(); 
} 
}) 
.setNegativeButton("注册", new DialogInterface.OnClickListener() { 
//否定按钮 
public void onClick(DialogInterface dialog, int whichButton) { 
//监听点击事件 
Toast.makeText(getApplicationContext(), "欢迎您注册为新 
用户", Toast.LENGTH_LONG).show(); 
} 
}) 
.setNeutralButton("退出", new DialogInterface.OnClickListener() { 
//中立按钮 
@Override 
public void onClick(DialogInterface dialogInterface, int i) { 
MainActivity.this.finish(); //退出程序 
} 
}); 
myDialogInstance.show(); //显示对话框 
} 
});

第5章 对话框、菜单和状态栏通知1 39 
5.1.2 日期和时间选择对话框
DatePickerDialog和TimePickerDialog用来显示日期选择和时间选择对话框。可以在程
序中直接通过new的方式实例化这两个类来得到对话框对象,二者的使用方法非常类似。
对于DatePickerDialog,其常用的构造方法定义如下: 
DatePickerDialog(Context con, OnDateSetListener call, int year, int month, 
int day) 
该方法有5个参数,其中第2个参数是一个DatePickerDialog.OnDateSetListener对
象,当用户选择好日期点击“确定”按钮时,会调用其中的onDateSet()方法。最后3个参
数分别用于指定对话框弹出时初始选择的年、月、日。
TimePickerDialog类常用的构造方法定义如下: 
TimePickerDialog(Context con, OnTimeSetListener call, int h, int m, boolean 
is24Hour) 
该方法有5个参数,其中第2个参数是一个TimePickerDialog.OnTimeSetListener 
对象,当用户选择好时间点击对话框上的“确定”按钮时,会调用其中的onTimeset()方
法。第3个参数和第4个参数为弹出对话框时初始显示的小时和分钟,最后一个参数设
置是否以24时制显示时间。
【例5-5】 示例工程Demo_05_DateAndTimePickerDialog演示了DatePickerDialog 
和TimePickerDialog的用法。
图5-5 示例工程的运行结果
在主界面的布局中定义两个按钮,点击第1个按钮,则弹出日期选择对话框,如图5-5(a) 
所示。点击“确定”按钮关闭对话框后,利用Toast显示所选择的日期。点击第2个按钮, 日期和时
间选择对
话框

1 40 Android软件开发教程(第3版·微课版) 
弹出时间选择对话框,如图5-5(b)所示。点击“确定”按钮关闭对话框后,利用Toast显
示所选择的时间。如果想要使弹出对话框时初始选择某一个日期或时间,可以利用
java.util.Calendar类获取日期或时间。
MainActivity类的主要代码如代码段5-7所示。 
代码段5-7 MainActivity 类的主要代码
//package 和import 语句略
public class MainActivity extends AppCompatActivity { 
@Override 
protected void onCreate(Bundle savedInstanceState) { 
super.onCreate(savedInstanceState); 
setContentView(R.layout.activity_main); 
Button btn1=(Button)findViewById(R.id.btn_1); 
btn1.setOnClickListener(new View.OnClickListener() { 
//"DatePickerDialog 示例"按钮 
public void onClick(View v) { 
//创建一个DatePickerDialog 
DatePickerDialog datePickerDialog=new DatePickerDialog 
(MainActivity.this, 
new DatePickerDialog.OnDateSetListener() { 
public void onDateSet(DatePicker view, int year, int 
monthOfYear, int dayOfMonth) { 
Toast.makeText(getApplicationContext(), "您选择的日 
期:"+ year+"-"+ (monthOfYear+ 1)+"-"+ dayOfMonth, 
Toast.LENGTH_LONG).show(); 
} 
}, 2020, 10, 6); 
datePickerDialog.show(); / /显示DatePickerDialog 
} 
}); 
Button btn2=(Button)findViewById(R.id.btn_2); 
btn2.setOnClickListener(new View.OnClickListener() { 
//"TimePickerDialog 示例"按钮 
public void onClick(View v) { 
//创建一个TimePickerDialog 
TimePickerDialog timePickerDialog = new TimePickerDialog 
(MainActivity.this, 
new TimePickerDialog.OnTimeSetListener() { 
public void onTimeSet(TimePicker view, int hourOfDay, 
int minute) { 
Toast.makeText(getApplicationContext(), "您选择的时 
间: "+ hourOfDay+":"+ minute, Toast.LENGTH_LONG). 
show();