本文是对网上的文章 Android 开发指南 - 用户界面 - 对话框的部分内容进行简化, 并加上自己的某些理解里面的相同内容, 版权归原翻译作者所有
显示对话框
对话框经常作为 Activity 的一部分来创建和显示你通常应该从 protected Dialog Activity.onCreateDialog (int id) 回调方法里创建对话框当你使用这个回调函数时, Android 系统会有效的设置这个 Activity 为每个对话框的所有者, 从而自动管理每个对话框的状态并挂靠到 Activity 上这样, 每个对话框继承这个 Activity 的特定属性比如, 当一个对话框打开时, 菜单键显示为这个 Activity 定义的选项菜单, 音量键修改 Activity 使用的音频流
注意: 如果你决定在 onCreateDialog()方法之外创建一个对话框, 它将不会被附着到活动上不过, 你可以通过 setOwnerActivity(Activity)把它附着到一个活动上
当你想要显示一个对话框时, 调用 showDialog(int id) 方法并传递一个唯一标识这个对话框的整数
当对话框第一次被请求时, Android 从你的 Activity 中调用 onCreateDialog(int id), 你应该在这里初始化这个对话框 Dialog 这个回调方法被传以和 showDialog(int id)相同的 ID 当你创建这个对话框后, 在 Activity 的最后返回这个对象
在对话框被显示之前, Android 还调用了可选的回调函数 onPrepareDialog(int id, Dialog). 如果你想在每一次对话框被打开时改变它的任何属性, 你可以定义这个方法这个方法在每次打开对话框时被调用, 而 onCreateDialog(int) 仅在对话框第一次打开时被调用如果你不定义 onPrepareDialog(), 那么这个对话框将保持和上次打开时一样这个方法也被传递以对话框的 ID, 和在 onCreateDialog()中创建的对话框对象(个人理解是, 在本 Activity 里第一次 show 某个 Dialog, 则先调用 onCreateDialog, 得到返回的 Dialog 对象并挂靠在 Activity, 保存 Dialog 对象的引用, 然后才显示 Dialog 这样子, 下次再 show Dialog 就不用重新创建 Dialog 对象, 而是重用旧的)
定义 onCreateDialog(int) 和 onPrepareDialog(int, Dialog) 回调函数的最佳方法是使用一个 switch 语句来检查传递进来的 id 参数每个 case 应该检查一个唯一的对话框 ID 然后创建和定义相应的对话框比如, 想象一下一个游戏使用两个不同的对话框: 一个用来指示这个游戏已经暂停而另一个来指示游戏结束首先, 为每个对话框定义一个常量:
- static final int DIALOG_PAUSED_ID = 0;
- static final int DIALOG_GAMEOVER_ID = 1;
然后, 为每一个 ID 用一个 switch case 定义这个 onCreateDialog(int) 回调函数:
- protected Dialog onCreateDialog(int id) { Dialog dialog;
- switch (id) {
- case DIALOG_PAUSED_ID:
- // do the work to define the pause Dialog
- break;
- case DIALOG_GAMEOVER_ID:
- // do the work to define the game over Dialog
- break;
- default:
- dialog = null;
- }
- return dialog;
- }
当是时候显示其中之一的对话框时, 使用对话框 ID 调用 showDialog(int):
showDialog(DIALOG_PAUSED_ID);
消除对话框 Dismissing a Dialog
当你准备关闭对话框时, 你可以通过对这个对话框调用 dismiss()来消除它如果需要, 你还可以从这个 Activity 中调用 dismissDialog(int id) 方法, 这实际上将为你对这个对话框调用 dismiss() 方法
如果你想使用 onCreateDialog(int id) 方法来管理你对话框的状态 (就如同在前面的章节讨论的那样), 然后每次你的对话框消除的时候, 这个对话框对象的状态将由该 Activity 保留如果你决定不再需要这个对象或者清除该状态是重要的, 那么你应该调用 removeDialog(int id) 这将删除任何内部对象引用而且如果这个对话框正在显示, 它将被消除
使用消除侦听器 Using dismiss listeners
如果你希望你的应用程序在一个对话框消亡的时候执行一些流程, 那么你应该附着一个 on-dismiss 侦听器到对话框上
- @Override
- protected void onPrepareDialog(int id, Dialog dialog) {
- switch(id){
- case PROGRESS_DIALOG:
- dialog.setOnDismissListener(new DialogInterface.OnDismissListener(){
- @Override
- public void onDismiss(DialogInterface dialog) {
- Toast.makeText(getApplicationContext(),
- "dismiss listener!",
- Toast.LENGTH_SHORT)
- .show();
- }
- });
- }
- }
然而, 请注意对话框也可以被取消这是一个表明对话框被用户显示取消的特殊情况这将在用户按返回按钮时发生, 或者这个对话框显示的调用 cancel() (也许通过对话框上的一个取消按钮)当一个对话框被取消时, 这个 OnDismissListener 依然会被通知到, 但是如果你希望在对话框被显示取消时被通知到 (而不是通常的消除方式), 那么你应该通过 setOnCancelListener() 注册一个 DialogInterface.OnCancelListener
目前个人学习发现, 一般情况下, 调用 dialog.cancel()就会触发 onCancelLister 而点击 AlertDialog 的 NegativeButton (Cancel/No)是不会触发的对于 setOnCancelListener()要注意的是, 这里有两个 setOnCancelListener(), 但返回值不同:
- //AlertDialog.Builder 调用的
- public AlertDialog.Builder setOnCancelListener (DialogInterface.OnCancelListener onCancelListener)
- //Dialog 调用的
- public void setOnCancelListener (DialogInterface.OnCancelListener listener)
警告对话框 AlertDialog 的使用
为了创建一个警告对话框, 使用 AlertDialog.Builder 子类通过 AlertDialog.Builder(Context)获取一个构造器然后使用这个类的公共方法来定义警告对话框的所有属性当得到构造器后, 通过 create(). 方法来获取警告对话框对象有时我是不调用 create()的, 而是在设置好了后直接调用 show()显示 AlertDialog
增加按钮 Adding buttons
这就是我一开始很想知道的究竟如何添加 Yes/No,Ok/Cancel 这样的按钮原来是通过 setPositiveButton(...)响应 Yes/Ok 的点击, setNeutralButton(...)响应中立行为的点击, setNegativeButton(...)响应 No/Cancel 的点击注意, 只能各自设置一个按钮来响应点击事件
- AlertDialog.Builder builder = new AlertDialog.Builder(this);
- builder.setMessage("Are you sure you want to exit?")
- .setCancelable(false)
- .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int id) {
- MyActivity.this.finish();
- }
- })
- .setNegativeButton("No", new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int id) {
- dialog.cancel();
- }
- });
- AlertDialog alert = builder.create();
首先, 为这个对话框添加一个消息 setMessage(CharSequence)然后, 开始函数链并设置该对话框为不能取消 not cancelable (因此用户不能使用返回按钮关闭这个对话框)对每个按钮, 使用任一 set...Button() 方法, 比如 setPositiveButton(), 该方法接受按钮名称以及一个定义用户选中按钮后所采取动作的 DialogInterface.OnClickListener
增加一个列表 Adding a list
- final CharSequence[] items = {"Red", "Green", "Blue"};
- AlertDialog.Builder builder = new AlertDialog.Builder(this);
- builder.setTitle("Pick a color");
- builder.setItems(items, new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int item) {
- Toast.makeText(getApplicationContext(), items[item], Toast.LENGTH_SHORT).show();
- }
- });
- AlertDialog alert = builder.create();
首先, 用 setTitle(CharSequence)方法给对话框添加一个标题然后, 添加用 setItems()添加一个可选项列表, 该列表接受一组显示的 items 和一个 DialogInterface.OnClickListener 来定义用户选中按钮后所采取动作
增加复选框和单选按钮
要在对话框里创建一个多选项列表 (checkboxes) 或者单选项 (radio buttons), 可分别调用 setMultiChoiceItems() 和 setSingleChoiceItems() 方法如果你在 onCreateDialog() 回调函数中创建这些可选列表, Android 会帮你管理列表状态只要这个活动是激活的, 对话框会记住之前选中的 items, 但如果用户退出这个活动, 用户选择将丢失
注意: 为了在用户离开或暂停这个活动的时候能够保存选择, 你必须通过活动生命期 Activity Lifecycle 来恰当的保存和恢复设置为了永久保存选项, 即使活动进程被完全终止, 你需要使用数据存储 Data Storage 技术
- final CharSequence[] items = {"Red", "Green", "Blue"};
- AlertDialog.Builder builder = new AlertDialog.Builder(this);
- builder.setTitle("Pick a color");
- builder.setSingleChoiceItems(items, -1, new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int item) {
- Toast.makeText(getApplicationContext(), items[item], Toast.LENGTH_SHORT).show();
- }
- });
- AlertDialog alert = builder.create();
setSingleChoiceItems() 的第二个参数是一个 checkedItem 整型数值, 指示了基于 0 的缺省选择项的位置 - 1 代表不会有默认选择项
进度对话框 Progress Dialog 的使用
ProgressDialog 是 AlertDialog 类的一个扩展, 可以为一个未定义进度的任务显示一个旋转轮形状的进度动画, 或者为一个指定进度的任务显示一个进度条
可以简单地通过调用 ProgressDialog.show()方法来显示一个进度对话框, 而通过 onCreateDialog(int)回调管理这个对话框是可选的, 如下所示:
- ProgressDialog.show(this, // context
- "", // title"Loading. Please wait...", // message
- true); // 进度是否是不确定的, 这只和创建进度条有关
进度对话框的缺省类型是一个旋转轮, 运行看到的是以下效果:
由于 ProgressDialog 是 AlertDialog 的扩展类, 所以 ProgressDialog 也能设置按钮, 比如一个取消下载的按钮不过要注意的是, 和前面的 AlertDialog.Builder 不同, ProgressDialog 是调用 AlertDialog 的 setButton,setButton2,setButton3 函数, 这些函数没有明确哪个是正面 / 中立 / 负面的, 由我们决定
显示进度条 Showing a progress bar
而选择动画进度条显示进度:
1. 用类构造器初始化进度对话框, ProgressDialog(Context)
2. 用 setProgressStyle(int)方法设置进度风格为 "STYLE_HORIZONTAL" 以及设置其它属性, 比如消息
创建 ProgressDialog 大概是这样的:
- ProgressDialog progressDialog = new ProgressDialog(getApplicationContext());
- progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
- progressDialog.setIcon(R.drawable.alert_dialog_icon);
- progressDialog.setMessage("Loading...");
- progressDialog.setCancelable(false);
3. 当你准备显示这个对话框时, 调用 show()或者从 onCreateDialog(int)回调中返回 ProgressDialog
4. 你可以通过调用 setProgress(int)设置当前进度百分比或者调用 incrementProgressBy(int)方法增加进度值
官方文档提供了如何在另一线程来跟踪进程进度, 让进度值变化对此可以参考 http://androidappdocs.appspot.com/guide/topics/ui/dialogs.html 里面的代码也可以查看后面的文章有关 Android 线程的学习里面的例子, 看看如何使用 Handler, Message 机制!
创建自定义对话框 Creating a Custom Dialog
创建自定义对话框, 首先要创建一个 Layout xml 文件, 在此不啰嗦了然后加载 Layout 有两种方法, 也是非常熟悉的那两种方法:
1. setContentView(int resources id)
2. 利用 LayoutInflater 加载
官方还提示我们, 一般使用 Dialog 类来创建对话框, 是需要 setTitle 的, 不设置的话, 标题占用的空间保持为空, 但仍然可见而不想要那个标题, 那应该使用警告对话框 AlertDialog 来创建自定义对话框然而, 因为警告对话框可以很简单的通过 AlertDialog.Builder 类来创建, 你并不需要访问上面使用的 setContentView(int) 方法相反, 你必须使用 setView(View), 则需要使用 LayoutInflater 来加载 Layout 得到 View
具体代码参考 http://androidappdocs.appspot.com/guide/topics/ui/dialogs.html
本文转自 Icansoft 51CTO 博客, 原文链接:
http://blog.51cto.com/android/333769
来源: https://yq.aliyun.com/articles/422016