android悬浮框横竖屏切换,Activity如何管理对话框(横竖屏切换保持对话框的最佳办法)...
在Activity中我们要保持横竖屏切换时用户的数据一般是用onSaveinstancestate的方式,dialog也是可以的,但是有更好的方法,Activity专门对dialog提供了自己的管理机制。
我们都知道Activity负责生成、保存、恢复对话框,下面我们就来了解一下Activity的对话框管理机制。
在Activity的源码中我们可以看到private static class ManagedDialog {
Dialog mDialog;
Bundle mArgs;
}
private SparseArray mManagedDialogs;
私有类ManagedDialog通过封装一个Dialog和一个Bundle保存对话框的引用及相关参数,另外使用一个SparseArray数组,来保存了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 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(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管理的全部.
android悬浮框横竖屏切换,Activity如何管理对话框(横竖屏切换保持对话框的最佳办法)...相关推荐
- Android悬浮框实践
1.常见悬浮框显示样式示例及应用场景 现在很多的应用都在使用悬浮框,例如微信视频,点击Home键以后,微信视频窗口一直停留在桌面上,小米手机屏幕上的快捷键(Home,锁屏...)等,那么我们今天将实现 ...
- WindowManager解析(二)Android悬浮框无法弹出输入法的原因和无需权限显示悬浮窗
Android悬浮框无法弹出输入法 最近要研究悬浮窗方面的东西,遇到一个问题,我的悬浮窗里面有一个输入框,但是不弹出输入法,后来找到一个方法: 在WindowManager的实例获取方式不对,之前是这 ...
- Android 悬浮框按钮
示例: 悬浮框的xml代码:(layout_float.xml) <?xml version="1.0" encoding="utf-8"?> &l ...
- 用WindowManager实现Android悬浮框以及拖动事件
下面的App程序代码实现通过主Activity的启动按钮,启动一个Service,然后在Service中创建添加悬浮窗口:(话不多说,直接上代码) 在这里我们先看一下需要创建的类和布局和需要添加的权限 ...
- Android零基础入门第76节:Activity数据保存和横竖屏切换
在前面几期学习了Activity的创建.配置.启动和停止,还学了Activity的生命周期,本期一起来学习Activity有关的更多事儿. 一.数据保存 通过上一期 LogCat 窗口打印的日志可以看 ...
- android 录屏不录制自身的悬浮框
通过MediaProjectionManager的录屏操作,做了个简单的应用,但是每次都把自身的悬浮框录制了进去,脑壳疼.使用系统自带的录屏工具就不会有这个问题.为了一探究竟,捣鼓出了系统的录屏工具a ...
- android录屏时不截入自定义悬浮框
前提:使用MediaProjectionManager录屏方案. 问题:会截入自定义悬浮框 解决方案 1.本质上得修改framework层代码surfaceflinger去除悬浮框,在画布中就去除该悬 ...
- android 浮动文字提示,怎么在Android中实现一个自由拖动并显示文字的悬浮框
怎么在Android中实现一个自由拖动并显示文字的悬浮框 发布时间:2021-01-27 15:34:05 来源:亿速云 阅读:107 作者:Leah 今天就跟大家聊聊有关怎么在Android中实现一 ...
- Android中的Window、WindowManager以及悬浮框视频播放的实现
摘要:近日看公司直播项目,其中有一个功能就是退出某房间之后,直播界面会以悬浮窗的形式出现,并且可以拖动悬浮窗到界面中任意位置,点击悬浮框之后,又可以回到房间中继续观看直播.现在这个功能在主流的直播或者 ...
最新文章
- 机器学习入门(05)— 使用 NumPy 实现 3 层简单神经网络
- 玩双节棍的算法工程师:鱼佬的数据挖掘之路!
- lucene全文搜索之三:生成索引字段,创建索引文档(给索引字段加权)基于lucene5.5.3...
- 活动安排(信息学奥赛一本通-T1422)
- 前端知识整理 CSS盒模型
- php生成超链接完整代码_PHP自动把网站自动添加超链接怎么写
- HTTP method POST is not supported by this URL解决方案
- 【数理统计】显著性检验
- 字号大小对应表(字号换算磅值)
- css斜线边框,CSS border斜线效果
- 个人搭建网站主要流程以及六个基本步骤
- win10虚拟机连接不上内网服务器,win10系统虚拟机无法连接网络的解决方法
- 微信PC版Hook发送群艾特消息研究
- 【福利】百度云2018最新限速破解软件
- 微信开发如何优雅的注入token(2)
- Pixelmator Pro Mac(图像编辑软件)
- Kanzi软件开发与Android的关系
- 日语里面用言连体,连用,终止形分别是什么
- libtool已经安装了 但是报错libtool not found, please install first
- 如何将solidworks中的机械臂三维装配体导出matlab可以运行或者说可以识别的STEP和XML格式