Android UI学习 - 对话框 (AlertDialog & ProgressDialog)

简介:

  本文是对网上的文章《Android开发指南-用户界面-对话框》的部分内容进行简化,并加上自己的某些理解。里面的相同内容,版权归原翻译作者所有。

显示对话框

    对话框经常作为Activity的一部分来创建和显示。你通常应该从protected Dialog Activity.onCreateDialog (int id) 回调方法里创建对话框。当你使用这个回调函数时,Android系统会有效的设置这个Activity为每个对话框的所有者,从而自动管理每个对话框的状态并挂靠到Activity上。这样,每个对话框继承这个Activity的特定属性。比如,当一个对话框打开时,菜单键显示为这个Activity定义的选项菜单,音量键修改Activity使用的音频流


 
 
  1. 注意: 如果你决定在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然后创建和定义相应的对话框。比如,想象一下一个游戏使用两个不同的对话框:一个用来指示这个游戏已经暂停而另一个来指示游戏结束。首先,为每个对话框定义一个常量:


 
 
  1. static final int DIALOG_PAUSED_ID = 0
  2. static final int DIALOG_GAMEOVER_ID = 1

然后,为每一个ID用一个switch case定义这个onCreateDialog(int) 回调函数:


 
 
  1. protected Dialog onCreateDialog(int id) { 
  2.     Dialog dialog; 
  3.     switch(id) { 
  4.     case DIALOG_PAUSED_ID: 
  5.         // do the work to define the pause Dialog 
  6.         break
  7.     case DIALOG_GAMEOVER_ID: 
  8.         // do the work to define the game over Dialog 
  9.         break
  10.     default
  11.         dialog = null
  12.     } 
  13.     return dialog; 

当是时候显示其中之一的对话框时,使用对话框ID调用showDialog(int):


 
 
  1. 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侦听器到对话框上。


 
 
  1. @Override 
  2. protected void onPrepareDialog(int id, Dialog dialog) { 
  3.     switch(id){ 
  4.     case PROGRESS_DIALOG: 
  5.         dialog.setOnDismissListener(new DialogInterface.OnDismissListener()
  6.             @Override 
  7.             public void onDismiss(DialogInterface dialog) { 
  8.                 Toast.makeText(getApplicationContext(), 
  9.                         "dismiss listener!"
  10.                         Toast.LENGTH_SHORT) 
  11.                 .show(); 
  12.             } 
  13.         }); 
  14.     } 

    然而, 请注意对话框也可以被“取消”。这是一个表明对话框被用户显示取消的特殊情况。这将在用户按“返回”按钮时发生,或者这个对话框显示的调用cancel() (也许通过对话框上的一个“取消”按钮)。当一个对话框被取消时,这个OnDismissListener 依然会被通知到,但是如果你希望在对话框被显示取消时被通知到(而不是通常的消除方式),那么你应该通过setOnCancelListener()注册一个DialogInterface.OnCancelListener 

    目前个人学习发现,一般情况下,调用dialog.cancel()就会触发onCancelLister。而点击AlertDialog的NegativeButton (Cancel/No)是不会触发的。对于setOnCancelListener()要注意的是,这里有两个setOnCancelListener(),但返回值不同:


 
 
  1. //AlertDialog.Builder调用的 
  2. public AlertDialog.Builder setOnCancelListener (DialogInterface.OnCancelListener onCancelListener) 
  3.  
  4. //Dialog调用的 
  5. public void setOnCancelListener (DialogInterface.OnCancelListener listener) 
 

警告对话框AlertDialog的使用

    为了创建一个警告对话框,使用AlertDialog.Builder 子类。通过AlertDialog.Builder(Context)获取一个构造器然后使用这个类的公共方法来定义警告对话框的所有属性。当得到构造器后,通过create().方法来获取警告对话框对象。有时我是不调用create()的,而是在设置好了后直接调用show()显示AlertDialog。

Dialog_button Dialog_button Dialog_button

增加按钮Adding buttons

    这就是我一开始很想知道的究竟如何添加Yes/No,Ok/Cancel这样的按钮。原来是通过setPositiveButton(...)响应Yes/Ok的点击,setNeutralButton(...)响应中立行为的点击,setNegativeButton(...)响应No/Cancel的点击。注意,只能各自设置一个按钮来响应点击事件。


 
 
  1. AlertDialog.Builder builder = new AlertDialog.Builder(this); 
  2. builder.setMessage("Are you sure you want to exit?"
  3.        .setCancelable(false
  4.        .setPositiveButton("Yes"new DialogInterface.OnClickListener() { 
  5.            public void onClick(DialogInterface dialog, int id) { 
  6.                 MyActivity.this.finish(); 
  7.            } 
  8.        }) 
  9.        .setNegativeButton("No"new DialogInterface.OnClickListener() { 
  10.            public void onClick(DialogInterface dialog, int id) { 
  11.                 dialog.cancel(); 
  12.            } 
  13.        }); 
  14. AlertDialog alert = builder.create(); 

    首先,为这个对话框添加一个消息setMessage(CharSequence)。然后,开始函数链并设置该对话框为不能取消not cancelable (因此用户不能使用返回按钮关闭这个对话框)。对每个按钮,使用任一set...Button() 方法,比如setPositiveButton(),该方法接受按钮名称以及一个定义用户选中按钮后所采取动作的DialogInterface.OnClickListener

增加一个列表Adding a list

 
 
  1. final CharSequence[] items = {"Red""Green""Blue"}; 
  2.   
  3. AlertDialog.Builder builder = new AlertDialog.Builder(this); 
  4. builder.setTitle("Pick a color"); 
  5. builder.setItems(items, new DialogInterface.OnClickListener() { 
  6.     public void onClick(DialogInterface dialog, int item) { 
  7.         Toast.makeText(getApplicationContext(), items[item], Toast.LENGTH_SHORT).show(); 
  8.     } 
  9. }); 
  10. AlertDialog alert = builder.create(); 

    首先,用setTitle(CharSequence)方法给对话框添加一个标题。然后,添加用setItems()添加一个可选项列表,该列表接受一组显示的items和一个DialogInterface.OnClickListener 来定义用户选中按钮后所采取动作。

增加复选框和单选按钮

    要在对话框里创建一个多选项列表(checkboxes)或者单选项(radio buttons),可分别调用setMultiChoiceItems() 和setSingleChoiceItems() 方法。如果你在onCreateDialog()回调函数中创建这些可选列表,Android会帮你管理列表状态。只要这个活动是激活的,对话框会记住之前选中的items,但如果用户退出这个活动,用户选择将丢失。

    注意: 为了在用户离开或暂停这个活动的时候能够保存选择,你必须通过活动生命期Activity Lifecycle来恰当的保存和恢复设置。为了永久保存选项,即使活动进程被完全终止,你需要使用数据存储Data Storage技术。


 
 
  1. final CharSequence[] items = {"Red""Green""Blue"}; 
  2.   
  3. AlertDialog.Builder builder = new AlertDialog.Builder(this); 
  4. builder.setTitle("Pick a color"); 
  5. builder.setSingleChoiceItems(items, -1new DialogInterface.OnClickListener() { 
  6.     public void onClick(DialogInterface dialog, int item) { 
  7.         Toast.makeText(getApplicationContext(), items[item], Toast.LENGTH_SHORT).show(); 
  8.     } 
  9. }); 
  10. AlertDialog alert = builder.create(); 

    setSingleChoiceItems() 的第二个参数是一个checkedItem整型数值,指示了基于0的缺省选择项的位置。“-1”代表不会有默认选择项。

 

进度对话框Progress Dialog的使用

    ProgressDialogAlertDialog类的一个扩展,可以为一个未定义进度的任务显示一个旋转轮形状的进度动画,或者为一个指定进度的任务显示一个进度条。

    可以简单地通过调用ProgressDialog.show()方法来显示一个进度对话框,而通过onCreateDialog(int)回调管理这个对话框是可选的,如下所示:


 
 
  1. ProgressDialog.show(this// context 
  2.     ""// title 
  3.     "Loading. Please wait..."// message 
  4.     true); //进度是否是不确定的,这只和创建进度条有关 

进度对话框的缺省类型是一个旋转轮,运行看到的是以下效果:

ProgressDialog

    由于ProgressDialog是AlertDialog的扩展类,所以ProgressDialog也能设置按钮,比如一个取消下载的按钮。不过要注意的是,和前面的AlertDialog.Builder不同,ProgressDialog是调用AlertDialogsetButtonsetButton2setButton3函数,这些函数没有明确哪个是正面/中立/负面的,由我们决定。

显示进度条Showing a progress bar

而选择动画进度条显示进度:

1.   用类构造器初始化进度对话框,ProgressDialog(Context)。

2.   用setProgressStyle(int)方法设置进度风格为"STYLE_HORIZONTAL"以及设置其它属性,比如消息。

创建ProgressDialog大概是这样的:


 
 
  1. ProgressDialog progressDialog = new ProgressDialog(getApplicationContext());  
  2.   
  3. progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);  
  4. progressDialog.setIcon(R.drawable.alert_dialog_icon);  
  5. progressDialog.setMessage("Loading...");  
  6. 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
相关文章
|
2月前
|
Java Maven 开发工具
第一个安卓项目 | 中国象棋demo学习
本文是作者关于其第一个安卓项目——中国象棋demo的学习记录,展示了demo的运行结果、爬坑记录以及参考资料,包括解决Android Studio和maven相关问题的方法。
第一个安卓项目 | 中国象棋demo学习
|
19天前
|
Web App开发 编解码 视频直播
视频直播技术干货(十二):从入门到放弃,快速学习Android端直播技术
本文详细介绍了Android端直播技术的全貌,涵盖了从实时音视频采集、编码、传输到解码与播放的各个环节。文章还探讨了直播中音视频同步、编解码器选择、传输协议以及直播延迟优化等关键问题。希望本文能为你提供有关Andriod端直播技术的深入理解和实践指导。
27 0
|
2月前
|
XML Android开发 UED
💥Android UI设计新风尚!掌握Material Design精髓,让你的界面颜值爆表!🎨
随着移动应用市场的蓬勃发展,用户对界面设计的要求日益提高。为此,掌握由Google推出的Material Design设计语言成为提升应用颜值和用户体验的关键。本文将带你深入了解Material Design的核心原则,如真实感、统一性和创新性,并通过丰富的组件库及示例代码,助你轻松打造美观且一致的应用界面。无论是色彩搭配还是动画效果,Material Design都能为你的Android应用增添无限魅力。
52 1
|
2月前
|
Android开发
Android学习 —— 测试init.rc中的条件触发的处理顺序
Android学习 —— 测试init.rc中的条件触发的处理顺序
|
3月前
|
存储 搜索推荐 Java
探索安卓开发中的自定义视图:打造个性化UI组件Java中的异常处理:从基础到高级
【8月更文挑战第29天】在安卓应用的海洋中,一个独特的用户界面(UI)能让应用脱颖而出。自定义视图是实现这一目标的强大工具。本文将通过一个简单的自定义计数器视图示例,展示如何从零开始创建一个具有独特风格和功能的安卓UI组件,并讨论在此过程中涉及的设计原则、性能优化和兼容性问题。准备好让你的应用与众不同了吗?让我们开始吧!
|
3月前
|
编解码 Android开发
【Android Studio】使用UI工具绘制,ConstraintLayout 限制性布局,快速上手
本文介绍了Android Studio中使用ConstraintLayout布局的方法,通过创建布局文件、设置控件约束等步骤,快速上手UI设计,并提供了一个TV Launcher界面布局的绘制示例。
49 1
|
3月前
|
API Android开发
Android使用AlertDialog实现弹出菜单
本文分享了在Android开发中使用AlertDialog实现弹出菜单的方法,并通过代码示例和错误处理,展示了如何避免因资源ID找不到导致的crash问题。
58 1
|
3月前
|
搜索推荐 Android开发
学习AOSP安卓系统源代码,需要什么样的电脑?不同配置的电脑,其编译时间有多大差距?
本文分享了不同价位电脑配置对于编译AOSP安卓系统源代码的影响,提供了从6000元到更高价位的电脑配置实例,并比较了它们的编译时间,以供学习AOSP源代码时电脑配置选择的参考。
198 0
学习AOSP安卓系统源代码,需要什么样的电脑?不同配置的电脑,其编译时间有多大差距?
|
3月前
|
API Android开发
Android项目架构设计问题之选择和使用合适的UI库如何解决
Android项目架构设计问题之选择和使用合适的UI库如何解决
43 0
|
3月前
|
前端开发 开发者 开发框架
JSF与Bootstrap,打造梦幻响应式网页!让你的应用跨设备,让用户爱不释手!
【8月更文挑战第31天】在现代Web应用开发中,响应式设计至关重要,以确保不同设备上的良好用户体验。本文探讨了JSF(JavaServer Faces)与Bootstrap框架的结合使用,展示了如何构建响应式网页。JSF是一个基于Java的Web应用框架,提供丰富的UI组件和表单处理功能;而Bootstrap则是一个基于HTML、CSS和JavaScript的前端框架,专注于实现响应式设计。通过结合两者的优势,开发者能够更便捷地创建自适应布局,提升Web应用体验。然而,这种组合也有其局限性,如JSF组件库较小和较高的学习成本等,因此在选择开发框架时需综合考虑具体需求和应用场景。
45 0