我们都知道Activity负责生成、保存、恢复对话框,下面我们就来了解一下Activity的对话框管理机制。
在Activity的源码中我们可以看到
private static class ManagedDialog {
Dialog mDialog;
Bundle mArgs;
}
private SparseArray<ManagedDialog> mManagedDialogs;
私有类ManagedDialog通过封装一个Dialog和一个Bundle保存对话框的引用及相关参数,另外使用一个SparseArray<ManagedDialog>数组,来保存了Activity生成的每一个对话框的信息。
SparseArray是一个升序排列的有序数组,采用Key+Value的方式形成类似于字典的数据结构,通过Key即可操作Value,其中Key是一个Int类型,Value是一个Object类型。该数组的内部搜索采用了二分查找算法,因此搜索速度很快。
下面我们来看一下显示对话框时的Activity中的处理机制。
public final boolean showDialog(int id, Bundle args) {
if (mManagedDialogs == null) {
mManagedDialogs = new SparseArray<ManagedDialog>();
}
ManagedDialog md = mManagedDialogs.get(id);
if (md == null) {
md = new ManagedDialog();
md.mDialog = createDialog(id, null, args);
if (md.mDialog == null) {
return false;
}
mManagedDialogs.put(id, md);
}
md.mArgs = args;
onPrepareDialog(id, md.mDialog, args);
md.mDialog.show();
return true;
}
从上面的代码不难看出,通过在mManagedDialogs数组中查找,可以判断指定id的对话框是否已经生成,如果没有生成,就新建一个ManagedDialog对象,为其mDialog创建一个对话框createDialog(),并将该ManagedDialog对象存入mManagedDialogs数组中;否则则直接调用onPrepareDialog()函数,能过show()将对话框显示出来。
这里值得一提的是createDialog()函数,其实现代码如下:
private Dialog createDialog(Integer dialogId, Bundle state, Bundle args) {
final Dialog dialog = onCreateDialog(dialogId, args);
if (dialog == null) {
return null;
}
dialog.dispatchOnCreate(state);
return dialog;
}
在该函数的第一行就回调了onCreateDialog()函数。
结合前面的代码可以发现,onCreateDialog()与onPrepareDialog()函数为我们提供了对对话框额外的处理能力,在我们自己的派生Activity中可以通过重写这两个函数来做一些特殊处理,但是需要注意的是,onCreateDialog()函数中在一个ID标识的对话框第一次创建的时候才会被回调,如果该对话框已经创建过,即使没有显示,由于存在于mManagedDialogs数组中,所以是不会再次触发onCreateDialog()函数的,但onPrepareDialog()函数是不受此限制的。
同样我们再来看一下隐藏对话框的代码。
public final void dismissDialog(int id) {
if (mManagedDialogs == null) {
throw missingDialog(id);
}
final ManagedDialog md = mManagedDialogs.get(id);
if (md == null) {
throw missingDialog(id);
}
md.mDialog.dismiss();
}
这段代码很简单,利用id在mManagedDialogs数组中找到ManagedDialog并调用其mDialog.dismiss()即可。
移除对话框也可以想见,只是从mManagedDialogs数组中remove()掉即可。
public final void removeDialog(int id) {
if (mManagedDialogs == null) {
return;
}
final ManagedDialog md = mManagedDialogs.get(id);
if (md == null) {
return;
}
md.mDialog.dismiss();
mManagedDialogs.remove(id);
}
我们知道Activity的生命周期,当Activity在前后台切换的时候,涉及到保存和恢复状态,这其中当然也要对对话框的状态进行处理,我们先来看一下当Activity切到后台时的状态保存处理。
private void saveManagedDialogs(Bundle outState) {
if (mManagedDialogs == null) {
return;
}
final int numDialogs = mManagedDialogs.size();
if (numDialogs == 0) {
return;
}
Bundle dialogState = new Bundle();
int[] ids = new int[mManagedDialogs.size()];
// save each dialog's bundle, gather the ids
for (int i = 0; i < numDialogs; i++) {
final int key = mManagedDialogs.keyAt(i);
ids[i] = key;
final ManagedDialog md = mManagedDialogs.valueAt(i);
dialogState.putBundle(savedDialogKeyFor(key), md.mDialog.onSaveInstanceState());
if (md.mArgs != null) {
dialogState.putBundle(savedDialogArgsKeyFor(key), md.mArgs);
}
}
dialogState.putIntArray(SAVED_DIALOG_IDS_KEY, ids);
outState.putBundle(SAVED_DIALOGS_TAG, dialogState);
}
整个的对话框信息保存用的是dialogState这个Bundle对象,遍历mManagedDialogs数组,对其中的每一个对话框信息,把对话框自身的onSaveInstanceState()返回的Bundle加入到dialogState中,再把对话框信息中保存的对话框参数存入dialogState中。最后将所有的对话框id形成的int数组再存入dialogState中,对话框的保存即告完成。
同理,恢复对话框是保存的逆过程,源码如下:
private void restoreManagedDialogs(Bundle savedInstanceState) {
final Bundle b = savedInstanceState.getBundle(SAVED_DIALOGS_TAG);
if (b == null) {
return;
}
final int[] ids = b.getIntArray(SAVED_DIALOG_IDS_KEY);
final int numDialogs = ids.length;
mManagedDialogs = new SparseArray<ManagedDialog>(numDialogs);
for (int i = 0; i < numDialogs; i++) {
final Integer dialogId = ids[i];
Bundle dialogState = b.getBundle(savedDialogKeyFor(dialogId));
if (dialogState != null) {
// Calling onRestoreInstanceState() below will invoke dispatchOnCreate
// so tell createDialog() not to do it, otherwise we get an exception
final ManagedDialog md = new ManagedDialog();
md.mArgs = b.getBundle(savedDialogArgsKeyFor(dialogId));
md.mDialog = createDialog(dialogId, dialogState, md.mArgs);
if (md.mDialog != null) {
mManagedDialogs.put(dialogId, md);
onPrepareDialog(dialogId, md.mDialog, md.mArgs);
md.mDialog.onRestoreInstanceState(dialogState);
}
}
}
}
到此,我们已经能够想到Activity在onDestory中如何销毁对话框了,没错,只要销毁mManagedDialogs数组就行了。
protected void onDestroy() {
// dismiss any dialogs we are managing.
if (mManagedDialogs != null) {
final int numDialogs = mManagedDialogs.size();
for (int i = 0; i < numDialogs; i++) {
final ManagedDialog md = mManagedDialogs.valueAt(i);
if (md.mDialog.isShowing()) {
md.mDialog.dismiss();
}
}
mManagedDialogs = null;
}
……
}
以上就是Activity对Dialog管理的全部,以后应该能更灵活的使用对话框了吧
——欢迎转载,请注明出处,谢谢——
分享到:
相关推荐
此外,"免费下载更多源码.url"可能是指向更多Android源码学习资源的链接,这对于深入理解Android开发非常有帮助。通过阅读和分析源码,开发者可以学习到最佳实践、优化技巧以及对Android框架的深入理解。 总的来说...
以上是"Android常用对话框源码--对话框大全"中的主要知识点,通过学习和实践这些,开发者可以熟练掌握Android应用中对话框的使用,提高用户体验。在实际开发中,可以根据需求灵活组合和定制,创造出符合应用特性的...
Android中的Dialog是一种轻量级的UI组件,它浮现在当前Activity之上,用于向用户展示重要的信息或者获取用户的输入。筛选对话框就是一种特殊类型的Dialog,用于让用户选择过滤条件。 2. **自定义Dialog** 在这个...
在Android开发中,Dialog对话框是一种非常常见的组件,它用于在主界面之上显示临时的通知或交互信息,而不中断用户与主界面的交互。本资源"安卓Dialog对话框相关-android自定义对话框.rar"包含了关于自定义Dialog的...
本资源"Android应用源码之android 自定义对话框.zip"包含了实现自定义对话框的源代码,这对于理解和实践Android对话框的定制化具有很高的参考价值。下面我们将深入探讨自定义对话框的相关知识点。 1. **对话框的...
在Android开发中,Dialog对话框是一种非常常见的组件,它用于在主界面之上显示临时的通知或获取用户的简单输入。本资源“安卓Dialog对话框相关-基本的对话框.rar”似乎包含了一些关于如何创建和使用基本Dialog的基本...
- 在这个项目中,源码可能包括一个自定义的DialogFragment,它是Android官方推荐用来在Fragment或Activity中展示对话框的方式。 - 源码可能包含一个Adapter类,用于绑定数据到ListView。Adapter通常需要重写`...
对话框在Android中主要由`android.app.Dialog`类表示,它是`Activity`的一个弹出窗口,通常悬浮在当前界面之上,用于展示额外的信息或执行特定任务。对话框分为几种类型,包括普通对话框、警告对话框、单选列表...
"安卓Android源码——-styled-dialogs可自定义样式的dialog.zip"是一个示例项目,它展示了如何在Android应用中创建和使用自定义样式的Dialog。该项目名为"android-styled-dialogs-master",我们可以从中学到以下几个...
本资源“安卓Android源码——android 自定义对话框.rar”显然包含了关于如何在Android平台上创建和定制对话框的源代码示例。通过这个压缩包,我们可以学习到如何摆脱系统默认样式,设计出更符合应用风格的对话框。 ...
这个毕业设计的源码提供了实践示例,适合学习者进一步研究和实践Android自定义对话框的实现细节。在实际开发中,自定义对话框是提升应用用户体验的重要手段,因此掌握其设计和实现技巧至关重要。
本项目聚焦于安卓app中的各种Dialog对话框的实现,提供完整的源码,这对于安卓毕业设计或者进阶学习者来说,是一个很好的实践和参考资源。以下是基于Dialog对话框的知识点详解: 1. **AlertDialog**:这是最常见的...
本资源“Android源码——普通对话框源码.zip”包含了一个关于如何实现Android普通对话框的源代码示例。下面将详细解释Android对话框的基本概念、创建方法以及源码中的关键点。 1. 对话框类型: Android中的对话框...
本项目“Android应用源码之进度条对话框Demo源码”是一个适用于毕业设计学习的示例,旨在帮助学生理解如何在Android应用程序中实现实时反馈机制。 首先,我们需要了解ProgressDialog的基本使用方法。在Android中,...
通过对“Android 普通对话框源码”的学习和理解,开发者可以更好地掌握如何在自己的应用中有效地使用对话框,提升用户体验。记得查看源码中的注释和逻辑,这将有助于深入理解对话框的工作原理和使用方法。
总之,"Android 半透明对话框Demo源码"是一个很好的学习材料,它涵盖了Android对话框的基本用法和自定义样式,对于学习Android UI设计和理解Activity与Fragment之间的交互有极大帮助。通过阅读和实践这个源码,你将...