Android 7.0正式版在近期开始进行了推送,该版本中最大的一个特色就是支持在设备上展示多窗口供用户查看各个应用。
如何切换到多窗口模式
多窗口模式有两种:分屏模式和自由形状模式。
分屏模式
进入分屏模式的操作:在overview屏幕下,长按Activity标题,然后可以拖动该 Activity 至屏幕突出显示的区域。
在分屏模式下,手指可以拖动分界线,放大其中一个应用,同时缩小另一个。如果这个应用在新展开的区域绘制滞后,系统将使用 windowBackground
属性或默认 windowBackgroundFallback
样式属性指定的颜色暂时填充该区域。
自由形状模式
进入自由形状模式的操作:稍微麻烦点,前提是要有运行 Android N 的模拟器或者已root的设备。目前为止(2016年9月初),在使用自由形状模式时可能Crash,所以google把该模式藏的比较深。开启和进入该模式的步骤如下:
- 打开模拟器或者用usb线连接已root了的设备
- 在cmd命令行中输入adb shell
- 然后输入su获得root操作权限
- 输入
settings put global enable_freeform_support 1
- 重启模拟器或设备。
- 进入自由形状模式:在overview屏幕下,长按Activity标题,将会在右边出现一个方块状的图标,点击该图标,该Activity该会以自由形状模式展示,通过对该Activity页面的左上角并拖拽,可以修改其形状大小。
多窗口生命周期
- 多窗口模式不会更改生命周期,多窗口模式下,最近的与用户进行交互的那个Activity为活动状态(Resume),所有其他的Activity虽然可见,但是都会处于暂停状态(pause)。但是这些已暂停但可见的 Activity 在系统中享有比不可见 Activity 更高的优先级。 如果用户与其中一个暂停的 Activity 交互,该 Activity 将恢复,而之前的顶级 Activity 将被暂停。
- 根据google官方文档上的描述,你如果在应用中做了视频播放效果,那么不要再在onPause中去暂停播放视频了,因为多窗口模式下,你的Activity虽然被暂停,但还是处于可见状态。建议在onStop方法中去暂停播放视频。
- 切换到多窗口时,Activity会发生配置变更,该变更与系统进行横竖屏切换时的 Activity 生命周期影响基本相同。你可以对 Activity 自行处理配置变更,或着默许系统去销毁 Activity,并以新的尺寸重新创建该 Activity。
如何禁用多窗口模式
- 如果应用需要适配Android N,那么,一定要注意你开发的应用在多窗口模式下的使用效果。
- Android 的SDK版本中给AndroidManifest里的Application(Activity)新增了一个属性:
android:resizeableActivity=["true" | "false"]
该属性为true时,将支持多窗口,为false时不支持,展示时只能是全屏模式(PS:该属性不配置时,默认为true)。Activity任务栈里第一个入栈的Activity的该属性,会被栈内的其他Activity继承。
比如说,任务栈中第一个入栈Activity里的resizeableActivity为true,那么即使接下来入栈的Activity的该属性为false,在多窗口模式下进行展示时,新入栈的Acitivity也不会强制进入全屏模式。
- 当你开发编译使用的SDK版本低于Android N时,那么多窗口模式下,你的应用会被系统强制性的修改页面大小,并且系统会弹出相应的Toast进行警告。
- 当你开发编译使用的SDK版本低于Android N时,如果你不希望系统去强制修改你的页面,比较偷懒的解决方案是:在AndroidMainifest中配置Applcaiton(或Activity任务栈里的首个入栈Activity)的android:screenOrientation属性。配了该属性后,你的页面将不支持多窗口,但是缺点就是Activity的朝向会被固定。(PS:这就是国内大部分应用目前不能展示在多窗口模式中的原因)
多窗口模式中一些被禁用的功能
在设备处于多窗口模式中时,某些功能会被禁用或忽略,因为这些功能对与其他 Activity 或应用共享设备屏幕的 Activity 而言没有意义。 此类功能包括:
- 某些系统 UI 自定义选项将被禁用;例如,在非全屏模式中,应用将无法去隐藏状态栏。
- 系统将忽略对
android:screenOrientation
属性所作的更改。
如果应用禁止多窗口支持
如果您通过设置 android:resizableActivity="false"
禁用了多窗口支持,则应在运行 Android N 的设备上启动应用,并尝试将应用切换到自由形状和分屏模式。 验证并确保执行此操作后,应用仍保持全屏模式。
如果应用需要多窗口支持
在多窗口模式中启动新 Activity
处于分屏模式中,在启动新 Activity 时,如果你想将新 Activity 显示在当前 Activity 的旁边那一屏。可使用标志Intent.FLAG_ACTIVITY_LAUNCH_TO_ADJACENT
。此标志将请求以下行为:
如果设备处于分屏模式,系统会尝试在启动系统的 Activity 旁创建新 Activity,这样两个 Activity 将共享屏幕。 系统并不一定能实现此操作,但如果可以,系统将使两个 Activity 处于相邻的位置。
-
如果设备不处于分屏模式,则该标志无效。
处于自由形状模式中,则在启动新 Activity 时,用户可使用
ActivityOptions.setLaunchBounds()
指定新 Activity 的尺寸和屏幕位置。 如果设备不处于多窗口模式,则该方法无效。
如果要在任务栈中启动 Activity,该 Activity 将替换屏幕上的 Activity,并继承其所有的多窗口属性。 如果想避免替换,让新Activity在多窗口模式中以另一个单独的窗口来展示,则必须让这个Activity在新的任务栈中来启动。
为多窗口模式准备的布局属性
对于 Android N,可以在清单文件的<Activity>
元素中支持以下几种属性,这些属性影响 Activity 会多窗口模式中的行为:
android:defaultWidth <!--以自由形状模式启动时 Activity 的默认宽度。-->
android:defaultHeight <!--以自由形状模式启动时 Activity 的默认高度。-->
android:gravity <!--以自由形状模式启动时 Activity 的初始位置。-->
android:minHeight、android:minWidth
<!-- 分屏和自由形状模式中 Activity 的最小高度和最小宽度。 如果用户在分屏模式中移动分界线,使 Activity 尺寸低于指定的最小值,系统会将 Activity 裁剪为用户请求的尺寸 -->
例如,以下节点显示了如何指定 Activity 在自由形状模式中显示时 Activity 的默认大小、位置和最小尺寸:
<activity android:name=".MyActivity">
<layout android:defaultHeight="400dp"
android:defaultWidth="400dp"
android:gravity="top|end"
android:minHeight="250dp"
android:minWidth="250dp" />
</activity>
多窗口变更通知和查询
Activity 类中添加了一些新方法,以支持多窗口显示:
/*调用该方法以确认 Activity 是否处于多窗口模式。*/
Activity.isInMultiWindowMode()
/*Activity 进入或退出多窗口模式时系统将调用此方法。 在 Activity 进入多窗口模式时,系统向该方法传递 true 值,在退出多窗口模式时,则传递 false 值。*/
Activity.onMultiWindowModeChanged()
每个方法还有 Fragment
版本,例如 Fragment.isInMultiWindowMode()
支持拖放
以前的版本中,只能在一个Activity中进行数据的拖放。在Android N中,多窗口模式下,可以在两个Activity之间互相拖放数据,因为篇(lan)幅(ai)有(fa)限(zuo),此处不再展开。
参考资料:
[google官方文档][https://developer.android.com/guide/topics/ui/multi-window.html]