不同设备上支持的分屏比例不同。
设备 |
竖屏 |
横屏 |
手机 |
全屏,或上下1:1/1:2/2:1 |
全屏,或左右1:1 |
折叠屏折叠态 |
全屏,或上下1:1/1:2/2:1 |
全屏,或左右1:1 |
折叠屏展开态 |
全屏,或左右1:1 |
全屏,或左右1:1 |
平板 |
全屏,或上下1:1/1:2/2:1 |
全屏,或左右1:1/1:2/2:1 |
5.3.1 分屏窗口适配指导说明
适用一步分屏方式触发,侧边应用栏触发等方式
1、应用如何声明支持分屏
在 <activity> 或 <application> 节点中设置resizeableActivity属性,启用或禁用多窗口显示:
<application
android:name=".MyActivity"
android:resizeableActivity=["true" | "false"] />
设置上述属性为true时,表明应用支持分屏,即可支持一步从全屏触发到分屏窗口。
应用在AndroidManifest.xml中targetSdk大于等于N(24)时,如果应用不显式声明该属性,则默认为true,即支持多窗口。
Android 12(API 级别 31)默认采用多窗口模式。在大屏 (sw >= 600dp) 设备上,不论应用配置为何,所有应用都会在多窗口模式下运行。
在小屏设备上,系统会检查 activity 的 minWidth、minHeight 和 resizeableActivity 设置以确定该 activity 能否在多窗口模式下运行。
根 activity 的属性设置会应用于其任务堆栈中的所有 activity。例如,如果根 activity 设置了 android:resizeableActivity="true",那么任务堆栈中的所有 activity 均可调整大小。
2. 正确使用应用资源
推荐使用Activity作为Context上下文加载合适的资源及做布局运算。如果使用的是 Application Context处理UI 相关的事情,你会发现加载的资源无法感知到多窗口。
使用activity获取特定窗口大小和屏幕大小
activity.getResources().getConfiguration().windowConfiguration.getBounds()
使用activity上下文从资源中获取窗口大小(dp):
activity.getResources().getConfiguration().screenHeightDp activity.getResources().getConfiguration().screenHeightDp
使用activity上下文从资源中获取窗口大小(px):
activity.getResources().getDisplayMetrics().widthPixels activity.getResources().getDisplayMetrics().heightPixels
使用activity上下文从display中获取窗口大小:
activity.getWindowManager().getDefaultDisplay().getMetrics(dm); activity.getWindowManager().getDefaultDisplay().getSize(point);
使用activity上下文从display中获取屏幕真实大小(获取屏幕大小也要尽量使用activity上下文,非activity上下文在多屏场景无法正确取到页面所在对应屏幕信息):
activity.getWindowManager().getDefaultDisplay().getRealMetrics(dm); activity.getWindowManager().getDefaultDisplay().getRealSize(point);
3、正确处理Configuration变化
Activity (和 Fragment) 将收到 onConfigurationChanged()方法回调而不是先销毁再重建,并且需要手工管理视图更新,重新加载资源等工作。
<activity
android:name=".MyActivity"
android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation|density" />
在同一块屏上的窗口尺寸大小发生变化时会产生这些变化:screenSize|smallestScreenSize|screenLayout|orientation, 窗口在多屏之间切换时可能还存在density的变化,故上述变化均需要监听和处理。
4、正确获取View的控件位置
多窗口情况下View.getLocationOnScreen和View.getLocationInWindow接口含义不同,前者拿到的控件在屏幕上的位置(相对屏幕左上角起点),后者是控件在窗口内部的位置(相对于窗口左上角起点)
5、Activity 提供以下方法来判别多窗口状态:
isInMultiWindowMode()
onMultiWindowModeChanged()
Fragement也提供了类似接口:Fragment.onMultiWindowModeChanged()。分屏和悬浮窗之间切换则不再通知,因为分屏和悬浮窗都是多窗口状态。
6、不要使用过渡栈中转页面
应用在启动时可能存在使用过渡页面中转的情形,使用过渡页面时不能单独起新栈,否则会导致多窗口的模式无法中继到最终的目标任务栈上,分屏和悬浮窗等多窗口模式都是以任务栈为单位,一旦跨栈则最终的目标栈就是全屏模式。
7、构建响应式布局
由于多窗口情况下,窗口尺寸会变化,最佳的用户体验,需要实现响应式布局,不同的尺寸下展示不同的布局,例如宽屏下的分栏。尽量根据应用的窗口尺寸大小进行动态布局,不要使用绝对布局。
注意事项
Android官方的多窗口设计文档如下:https://developer.android.com/guide/topics/ui/multi-window.html
单个应用组成的分屏,两侧屏幕可以同时展示不同的任务或都展示同一个任务。例如当前正在全屏使用应用A,再在侧边栏长按后拖出应用A,应用A形成单应用多任务的分屏组合。

目前仅部分支持多实例的应用可以单应用分屏,通过侧边栏触发分屏时,使用应用的图标颜色来帮助判断,该应用是否支持单应用分屏
下图为全屏使用应用A的场景,拖出侧边栏后通过侧边栏中应用A图标的颜色来辅助判断:若侧边栏中应用A图标正常显示,则表示支持应用A分屏;若侧边栏中应用A图标置灰,则表示不支持应用A分屏。
畅联不支持单应用分屏的示例 |
备忘录支持单应用分屏的示例 |
示例
单应用启动的多个分屏任务和多个悬浮窗口任务相似,适用于同类型且同时操作的场景,移动办公类居多,例如:
1)文档处理应用同时打开多个文档窗口
2)记事本、邮件类同时打开多个编辑框界面等
应用在启动的多个实例窗口之间无依赖关系,彼此独立,且可以快速结束,使用完毕主动去finish销毁activity窗口。
单应用多实例运行到分屏示例代码,以示例页面“com.huawei.android.extdisplay.test.MultiFreeformTestActivity”为例,将其启动到分屏多任务代码如下:
Intent intent = new Intent(); intent.setClassName(this, "com.huawei.android.extdisplay.test.MultiFreeformTestActivity"); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK | Intent. FLAG_ACTIVITY_RETAIN_IN_RECENTS); ActivityOptions options = ActivityOptions.makeBasic(); ActivityManagerEx.setLaunchWindowingMode(options, ActivityManagerEx.HW_MULTI_WINDOWING_MODE_SECONDARY, this); this.startActivity(intent, options.toBundle());
允许起多个实例的activity不能配置singleTask和singleInstance标记,且应用需要声明以下metadata信息供系统识别app是否支持多实例
<meta-data
android:name="com.huawei.android.multiwindow.multiinstance.enable"
android:value="true">
</meta-data> 单个应用内更加灵活的不同类型和层级的界面,同时以分屏窗口形式显示时,在后续章节平行视界中介绍。