支持桌面窗口化

借助桌面窗口功能,用户可以在可调整大小的应用窗口中同时运行多个应用,从而获得类似桌面的多样化体验。

在图 1 中,您可以看到启用桌面窗口化后的屏幕布局。需注意的事项:

  • 用户可以同时并排运行多个应用。
  • 任务栏位于显示屏底部的固定位置,用于显示正在运行的应用。用户可以将应用固定起来,以便快速访问。
  • 新的可自定义标题栏会使用最小化和最大化等控件装饰每个窗口的顶部。
图 1. 平板电脑上的桌面设备窗口。

默认情况下,应用会在 Android 平板电脑上以全屏模式打开。 如需在桌面窗口化模式下启动应用,请按住屏幕顶部的窗口手柄,然后将手柄拖动到界面中,如图 2 所示。

当一个应用在桌面窗口中打开时,其他应用在桌面窗口中打开时将作为 。

图 2. 按住并拖动应用窗口手柄即可进入桌面窗口模式。

用户还可以从 窗口手柄(当您点按或点击手柄或使用键盘快捷键时) Meta 键(Windows、Command 或搜索键)+ Ctrl + 向下键

用户可以通过关闭所有活动窗口或抓住桌面窗口顶部的窗口手柄并将应用拖动到屏幕顶部来退出桌面窗口化。Meta + H 键盘快捷键也会退出 并再次全屏运行应用。

如需返回桌面窗口模式,请点按或点击“最近用过”屏幕中的桌面工作区功能块。

可调整大小和兼容模式

在桌面窗口中,屏幕方向锁定的应用可随意调整大小。 这意味着,即使某个 activity 锁定为纵向,用户仍可以将应用调整为横向窗口。

图 3. 将仅限纵向的应用的窗口大小调整为横向。

应用声明为不可调整大小(即 resizableActivity = false) 在保持相同的宽高比的同时缩放界面。

图 4. 不可调整大小的应用的界面会随着窗口大小的调整而缩放。

锁定屏幕方向或声明为不可调整大小的相机应用会对其相机取景器进行特殊处理:窗口可完全调整大小,但取景器会保持相同的宽高比。通过假设应用 始终在纵向或横向模式下运行,但应用会硬编码或以其他方式 会导致预览或所拍摄图片计算错误的假设 导致图片发生拉伸、侧视或上下颠倒。

在应用准备好实现完全响应的相机取景器之前,特殊处理可提供更基本的用户体验,从而减轻错误假设可能造成的影响。

如需详细了解相机应用的兼容性模式,请参阅设备兼容性模式

图 5. 窗口大小调整时,相机取景器的宽高比保持不变。

可自定义的标题边衬区

在桌面窗口中运行的所有应用都有一个标题栏,即使在 沉浸模式
确保应用内容不会被标题栏遮挡。 标题栏是一种标题栏边衬区: androidx.compose.foundation.layout.WindowInsets.Companion.captionBar(); 在观看次数中,WindowInsets.Type.captionBar(), 这是系统栏的一部分

如需详细了解如何处理内边距,请参阅在应用中以无边框方式显示内容并在 Compose 中处理窗口内边距

标题栏也可自定义。Android 15 引入了外观类型 APPEARANCE_TRANSPARENT_CAPTION_BAR_BACKGROUND 标题栏是透明的,以便应用在其中绘制自定义内容 。

然后,应用会负责设置内容顶部的样式, 图片说明栏(背景、自定义内容等), 系统字幕元素(关闭和最大化按钮)除外,这些 由系统在应用顶部的透明标题栏中绘制而成。

应用可以使用 APPEARANCE_LIGHT_CAPTION_BARS 在浅色和深色主题中切换标题中系统元素的外观,这与切换状态栏和导航栏的方式类似。

Android 15 还引入了 WindowInsets#getBoundingRects() 方法,可让应用更详细地自省标题栏内嵌。应用可以区分系统绘制系统元素和 未使用的区域,应用可在这些区域放置自定义内容,而不重叠系统元素。

API 返回的 Rect 对象列表指示应避免的系统区域。任何剩余空间(通过减去矩形所得数计算得出) 即图片说明栏的边衬区) 相互重叠的系统元素,并且能够接收输入。

实现自定义标头之前和之后的 Chrome。
图 6. Chrome 实现自定义标头前后的对比。

支持多任务处理和多实例

多任务处理是桌面设备窗口的核心, 可以大幅提高用户的工作效率。

Android 15 引入了 PROPERTY_SUPPORTS_MULTI_INSTANCE_SYSTEM_UI,应用可以设置此属性,以指定应为应用显示系统界面,以允许其以多个实例启动。

使用拖动手势管理应用实例

在多窗口模式下,用户可以通过拖动视图来启动新的应用实例 将元素移出应用窗口。 用户还可以在同一应用的实例之间移动元素。

图 7. 将标签页拖出桌面窗口,创建一个新的 Chrome 实例。

Android 15 引入了两个标记来自定义拖放行为:

  • DRAG_FLAG_START_INTENT_SENDER_ON_UNHANDLED_DRAG: 表示应将未处理的拖动委托给系统才能启动 如果没有可见窗口处理放下操作,则会发生此错误。 使用此标记时,调用方必须提供 ClipData,带有 Item,其中包含 不可变的 IntentSender 更改为 要启动的 activity (请参阅 ClipData.Item.Builder#setIntentSender())。 系统可以根据当前屏幕等因素来启动或不启动 intent 或窗口模式。如果系统未启动 intent,系统会通过正常的拖放流程取消 intent。

  • DRAG_FLAG_GLOBAL_SAME_APPLICATION:表示拖动操作可以跨窗口边界(适用于同一应用的多个实例)。

    startDragAndDrop() 时 在使用此标志时进行调用,系统只会调用属于同一 应用能够参与拖动操作并接收拖动的内容。

图 8. 在 Chrome 应用的两个实例之间移动标签页。

其他优化措施

自定义应用启动方式,并将应用从桌面窗口模式转换为全屏模式。

指定默认大小和位置

并非所有应用(即使可调整大小)都需要大窗口来为用户提供价值。您可以使用 ActivityOptions#setLaunchBounds() 方法指定 activity 启动时的默认尺寸和位置。

从桌面空间进入全屏模式

应用可以通过调用 Activity#requestFullScreenMode() 以编程方式进入全屏模式。该方法可直接从桌面窗口化模式将应用置于全屏模式。