2011横竖登陆框设计修改

 ›  › 
Activity如何管理对话框(横竖屏切换保持对话框的最佳办法)
在Activity中我们要保持横竖屏切换时用户的数据一般是用onSaveinstancestate的方式,dialog也是可以的,但是有更好的方法,Activity专门对dialog提供了自己的管理机制。我们都知道Activity负责生成、保存、恢复对话框,下面我们就来了解一下Activity的对话框管理机制。在Activity的源码中我们可以看到private static class ManagedDialog {
&&&&Dialog mD
&&&&Bundle mA
private SparseArray&ManagedDialog& mManagedD私有类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) {
&&&&&&&&&&&&
&&&&&&&&mManagedDialogs.put(id, md);
&&&&md.mArgs =
&&&&onPrepareDialog(id, md.mDialog, args);
&&&&md.mDialog.show();
}从上面的代码不难看出,通过在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) {
&&&&dialog.dispatchOnCreate(state);
}在该函数的第一行就回调了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) {
&&&&&final ManagedDialog md = mManagedDialogs.get(id);
&&&&&if (md == null) {
&&&&&md.mDialog.dismiss();
&&&&&mManagedDialogs.remove(id);
&}我们知道Activity的生命周期,当Activity在前后台切换的时候,涉及到保存和恢复状态,这其中当然也要对对话框的状态进行处理,我们先来看一下当Activity切到后台时的状态保存处理。&&&&private void saveManagedDialogs(Bundle outState) {
&&&&&&&&if (mManagedDialogs == null) {
&&&&&&&&&&&&
&&&&&&&&final int numDialogs = mManagedDialogs.size();
&&&&&&&&if (numDialogs == 0) {
&&&&&&&&&&&&
&&&&&&&&Bundle dialogState = new Bundle();
&&&&&&&&int[] ids = new int[mManagedDialogs.size()];
&&&&&&&&// save each dialog's bundle, gather the ids
&&&&&&&&for (int i = 0; i & numD i++) {
&&&&&&&&&&&&final int key = mManagedDialogs.keyAt(i);
&&&&&&&&&&&&ids[i] =
&&&&&&&&&&&&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(S***ED_DIALOG_IDS_KEY, ids);
&&&&&&&&outState.putBundle(S***ED_DIALOGS_TAG, dialogState);
}整个的对话框信息保存用的是dialogState这个Bundle对象,遍历mManagedDialogs数组,对其中的每一个对话框信息,把对话框自身的onSaveInstanceState()返回的Bundle加入到dialogState中,再把对话框信息中保存的对话框参数存入dialogState中。最后将所有的对话框id形成的int数组再存入dialogState中,对话框的保存即告完成。同理,恢复对话框是保存的逆过程,源码如下:private void restoreManagedDialogs(Bundle savedInstanceState) {
&&&&final Bundle b = savedInstanceState.getBundle(S***ED_DIALOGS_TAG);
&&&&if (b == null) {
&&&&final int[] ids = b.getIntArray(S***ED_DIALOG_IDS_KEY);
&&&&final int numDialogs = ids.
&&&&mManagedDialogs = new SparseArray&ManagedDialog&(numDialogs);
&&&&for (int i = 0; i & numD 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 & numD i++) {
&&&&&&&&&&&&final ManagedDialog md = mManagedDialogs.valueAt(i);
&&&&&&&&&&&&if (md.mDialog.isShowing()) {
&&&&&&&&&&&&&&&&md.mDialog.dismiss();
&&&&&&&&&&&&}
&&&&&&&&mManagedDialogs =
}以上就是Activity对Dialog管理的全部.
上一篇: 本示例介绍如何使用Android系统样式和自定义样式创建半透明界面。 1. 定义清单文件( AndroidManifest.xml ) ?xmlversion="1.0"encoding="utf-8"?manifestxmlns:android="/apk/res/android"package="my.andriod.test"android:ver
下一篇: Android 4.0增加了对光标悬停事件、手写笔、鼠标按钮事件的支持。 悬停事件 View类现在支持“悬停”事件,通过对指针设备(如鼠标或其他设备驱动屏幕上的光标)支持,使得其用户交互更加丰富。 为了接收控件上的悬停事件,需要实现View.OnHoverListener,并

参考资料

 

随机推荐