7.2.3 对话框

除了界面组件,对话框(Dialog)也是一个重要的交互单元。与界面组件不同,对话框并不能作为独立组件存在,而是需要寄宿在某个界面组件中。与界面组件相比,对话框的构造更为轻量,生命周期更为简单,数据传输也更为快捷。因此,它常作为临时的辅助交互对象,将相关信息提示给用户,或接受一些用户的输入信息(如图7-7所示)。

在Android中,对话框都派生自android.app.Dialog类。与界面组件相同的是,在每个Dialog对象中也包含一个Window对象,负责控件树的管理和构造。因此,从界面控件构成来看,界面组件与对话框并没有太多不同之处,只是在具体呈现的细节上,根据两者的应用场景略有不同。

7.2.3 对话框 - 图1

图 7-7 Android对话框示例

Dialog类中最常用的子类是android.app.AlertDialog,它将对话框的界面样式进一步限定成了三块区域:标题区域、内容区域和操作区域,使其更符合用户与对话框交互的需求。开发者往往不会直接构造AlertDialog对象,而是通过android.app.AlertDialog.Builder对象辅助构造。AlertDialog.Builder对象中提供了链式操作的接口,使开发者可以更方便地构造对话框对象:


//在界面组件中构造并展现一个对话框对象

new AlertDialog.Builder(this)

.setTitle("对话框标题")//设置标题

.setMessage("对话框内容")//设置对话框的提示信息

.setPositiveButton("关闭",new OnClickListener(){

//可以在对话框关闭前做一些处理

})

.show();


在AlertDialog对话框对象中,标题区域用于告诉用户该对话框对象期望完成的主要任务,它由图标和标题文字共同构成,开发者可以通过AlertDialog.Builder.setIcon和AlertDialog.Builder.setTitle函数来设置图标和文字,也可以通过AlertDialog.Builder.setCustomTitle函数来自定义标题样式和内容。

内容区域则用于设置提示信息,或接受用户输入信息。AlertDialog.Builder对象提供了大量的便捷接口供开发者使用,比如可以通过AlertDialog.Builder.setMessage设置提醒的文字信息,也可以通过AlertDialog.Builder.setItems函数设置选择列表,抑或可以通过AlertDialog.Builder.setView自定义内容区域的样式。

操作区域则是由0~3个水平排列的按钮构成,开发者可以通过AlertDialog.Builder.setPositiveButton等函数来设置按钮的文字信息以及处理按钮的点击事件。每个按钮点击后,都会导致对话框消隐。除此之外,通过Dialog.cancel函数或设备上的返回键都可以取消并消隐该对话框对象,开发者可以通过AlertDialog.Builder.setOnCancelListener来监听该事件。

与可选菜单项类似,对话框对象的构造比较耗时,可能会导致界面阻塞。因此,如果一个对话框对象在界面组件中需要反复使用,则需要利用缓存机制,以避免对其反复进行构造和销毁。在界面组件中,可以通过Activity.showDialog函数来弹出指定的对话框对象,开发者需要在Activity.onCreateDialog函数中对其进行构造。对话框对象一旦被构造,就会被缓存下来。开发者可以通过Activity.dismissDialog函数消隐该对话框,但这并不会导致该对话框对象的销毁。如果开发者期望提前释放该对象占据的内存空间,可以调用Activity.removeDialog函数删除缓存的对话框对象。每次对话框呈现之前,都会调用Activity.onPrepareDialog函数,开发者可以通过重载该函数动态地变更对话框对象中的内容。

利用这种模式构建对话框对象,不仅能够避免反复构建对话框对象,还可以将对话框对象融入到界面组件的生命周期内。当界面组件被系统强行回收时,它会先遍历缓存在其中的对话框对象,调用它们的Dialog.onSaveInstanceState函数,保存对话框对象的交互状态;在组件被再次重构时,再调用对话框对象的Dialog.onRestoreIntanceState函数,将其恢复至回收之前的状态,保证用户在对话框中输入的状态信息不会丢失。