我们很高兴地宣布,在 Android 上将移动和桌面计算紧密结合方面,我们取得了主要里程碑:外接显示器支持已随 Android 16 QPR3 版本正式版发布!
正如 Google I/O 2025 上展示的那样,外接显示器可让用户将 Android 设备连接到外部显示器,并立即访问桌面窗口化模式环境。应用可以在自由形状窗口或最大化窗口中使用,用户可以像在桌面操作系统上一样执行多任务处理。
Google 和 Samsung 携手合作,为 Android 生态系统中运行 Android 16 的设备带来顺畅而强大的桌面窗口化模式体验,同时还可连接到外接显示屏。
此功能现已在受支持的设备* 上面向可将受支持的 Pixel 和 Samsung 手机连接到外部显示器的用户全面推出,从而为打造更具吸引力、更高效的应用体验创造了新的机会,这些应用体验可适应各种设备规格。
运作方式
当受支持的 Android 手机或可折叠设备连接到外接显示器时,外接显示器上会启动新的桌面会话。
外接显示器上的体验与桌面设备上的体验类似,包括显示活动应用的任务栏,以及允许用户固定应用以便快速访问。用户可以在外接显示器上以可自由调整大小的窗口并排同时运行多个应用。
手机连接到外接显示屏,显示屏上显示桌面会话,同时手机保持自身状态。
当支持桌面窗口化模式的设备(例如 Samsung Galaxy Tab S11 等平板电脑)连接到外接显示屏时,桌面会话会扩展到这两个显示屏,从而解锁更广阔的工作区。这两个显示屏相当于一个无缝衔接的整体,应用窗口、内容和光标都可以在两屏之间自由移动。
平板电脑连接到外接显示屏,将桌面会话扩展到两个显示屏。
它为何重要?
在 Android 16 QPR3 版本中,我们最终确定了窗口化行为、任务栏互动和输入兼容性(鼠标和键盘),这些因素定义了外接显示器的体验。我们还纳入了兼容性处理,以便在切换显示屏时缩放窗口并避免应用重启。
如果您的应用是根据自适应设计原则构建的,它将自动具有桌面版的外观和风格,用户会感觉非常熟悉。如果应用锁定为竖屏模式或假定为仅限触控的界面,现在是时候进行现代化改造了。
具体而言,请注意以下关键最佳实践,以便在外接显示屏上获得最佳应用体验:
- 请勿假定
Display对象保持不变:当应用窗口移至外部显示屏或显示配置发生变化时,与应用上下文关联的Display对象可能会发生变化。您的应用应妥善处理配置更改事件,并动态查询显示指标,而不是缓存这些指标。 - 考虑密度配置变化:外部显示屏的像素密度可能与主设备屏幕的像素密度截然不同。确保布局和资源能够正确适应这些变化,以保持界面清晰度和可用性。为布局使用密度无关像素 (dp)、提供密度特定的资源,并确保界面可适当缩放。
- 正确支持外部外围设备:当用户把设备连接到外部显示屏时,通常会营造一个更像桌面设备的使用环境。这常常涉及使用外接键盘、鼠标、触控板、摄像头、麦克风和音箱。改进了对键盘和鼠标互动操作的支持。
利用现代工具打造桌面设备的未来
我们提供了多种工具来帮助您打造桌面版体验。我们来回顾一下核心自适应库的最新更新!
新的窗口大小类:“大”和“超大”
Jetpack WindowManager 1.5.0 中最大的更新是新增了两个宽度窗口大小类:“大”和“超大”。
窗口大小类是我们官方提供的一组主观的视口划分点,有助于您设计和开发自适应布局。在 1.5.0 中,我们将此指南的适用范围扩展到超出典型平板电脑尺寸的屏幕。
以下是新的宽度断点:
- 大:适用于宽度介于 1200dp 和 1600dp 之间的屏幕
- 超大:适用于宽度 ≥1600dp 的屏幕
基于显示宽度的不同窗口大小类别。
在非常大的界面上,简单地放大平板电脑的展开布局并不总是能提供最佳用户体验。例如,电子邮件客户端可能可以在展开窗口尺寸类中轻松显示两个窗格(邮箱和邮件)。但在超大桌面显示器上,电子邮件客户端可以同时优雅地显示三个甚至四个窗格,例如邮箱、邮件列表、完整邮件内容和日历/任务面板。
如需在项目中包含新的窗口大小类,只需从 WindowSizeClass.BREAKPOINTS_V2 集调用该函数,而不是从 WindowSizeClass.BREAKPOINTS_V1 调用:
val currentWindowMetrics =
WindowMetricsCalculator.getOrCreate()
.computeCurrentWindowMetrics(LocalContext.current)
val sizeClass = WindowSizeClass.BREAKPOINTS_V2
.computeWindowSizeClass(currentWindowMetrics)然后,在确定应用至少有这么多空间时,应用正确的布局:
if(sizeClass.isWidthAtLeastBreakpoint(
WindowSizeClass.WIDTH_DP_LARGE_LOWER_BOUND)){
...
// Window is at least 1200 dp wide.
}使用 Jetpack Navigation 3 构建自适应布局
Navigation 3 是 Jetpack 系列的最新成员。Navigation 3 刚刚发布了第一个稳定版本,是一个功能强大的导航库,旨在与 Compose 搭配使用。
Navigation 3 也是一个出色的工具,可让您同时显示多个目的地,并在这些布局之间无缝切换,从而构建自适应布局。
此系统基于场景来管理应用的界面流程。场景是一种同时显示一个或多个目的地的布局。SceneStrategy 用于确定是否可以创建场景。通过将 SceneStrategy 实例链接在一起,您可以针对不同的屏幕尺寸和设备配置创建并显示不同的场景。
对于开箱即用的规范布局(例如列表-详情和辅助窗格),您可以使用 Compose Material 3 Adaptive 库中的场景(可在版本 1.3 及更高版本中使用)。
您还可以通过修改场景配方或从头开始轻松构建自己的自定义场景。例如,假设有一个场景并排显示三个窗格:
class ThreePaneScene<T : Any>(
override val key: Any,
override val previousEntries: List<NavEntry<T>>,
val firstEntry: NavEntry<T>,
val secondEntry: NavEntry<T>,
val thirdEntry: NavEntry<T>
) : Scene<T> {
override val entries: List<NavEntry<T>> = listOf(firstEntry, secondEntry, thirdEntry)
override val content: @Composable (() -> Unit) = {
Row(modifier = Modifier.fillMaxSize()) {
Column(modifier = Modifier.weight(1f)) {
firstEntry.Content()
}
Column(modifier = Modifier.weight(1f)) {
secondEntry.Content()
}
Column(modifier = Modifier.weight(1f)) {
thirdEntry.Content()
}
}
}在这种情况下,您可以定义一个 SceneStrategy,以便在窗口宽度足够大时显示三个窗格,并且返回堆栈中的条目已声明它们支持在三窗格场景中显示。
class ThreePaneSceneStrategy<T : Any>(val windowSizeClass: WindowSizeClass) : SceneStrategy<T> {
override fun SceneStrategyScope<T>.calculateScene(entries: List<NavEntry<T>>): Scene<T>? {
if (windowSizeClass.isWidthAtLeastBreakpoint(WIDTH_DP_LARGE_LOWER_BOUND)) {
val lastThree = entries.takeLast(3)
if (lastThree.size == 3 && lastThree.all { it.metadata.containsKey(MULTI_PANE_KEY) }) {
val firstEntry = lastThree[0]
val secondEntry = lastThree[1]
val thirdEntry = lastThree[2]
return ThreePaneScene(
key = Triple(firstEntry.contentKey, secondEntry.contentKey, thirdEntry.contentKey),
previousEntries = entries.dropLast(3),
firstEntry = firstEntry,
secondEntry = secondEntry,
thirdEntry = thirdEntry
)
}
}
return null
}
}创建 NavDisplay 时,您可以将 ThreePaneSceneStrategy 与其他策略搭配使用。例如,我们还可以添加 TwoPaneStrategy,以便在空间不足以显示三个窗格时并排显示两个窗格。
val strategy = ThreePaneSceneStrategy() then TwoPaneSceneStrategy()
NavDisplay(...,
sceneStrategy = strategy,
entryProvider = entryProvider {
entry<MyScreen>(metadata = mapOf(MULTI_PANE_KEY to true))) { ... }
... other entries...
}
)如果没有足够的空间来显示三个或两个窗格,我们的两种自定义场景策略都会返回 null。在这种情况下,NavDisplay 会回退为使用 SinglePaneScene 在单个窗格中显示返回堆栈中的最后一个条目。
通过使用场景和策略,您可以为应用添加单窗格、双窗格和三窗格布局!
自适应应用在宽屏上显示三窗格导航。
如需详细了解如何在 Navigation 3 中使用场景创建自定义布局,请查看相关文档。
独立自适应布局
如果您需要独立布局,Compose Material 3 自适应库可帮助您创建自适应界面,例如列表-详情和支持窗格布局,这些布局可根据窗口大小类别或设备姿态自动调整自身以适应窗口配置。
好消息是,该库已更新为新的断点!从版本 1.2 开始,默认窗格支架指令函数支持“大”和“超大”宽度窗口大小类别。
您只需在 Gradle build 文件中声明要使用新的断点,即可选择启用该功能:
currentWindowAdaptiveInfo(supportLargeAndXLargeWidth = true)
使用入门
探索最新 Android 版本中的外接显示器功能。在受支持的设备上获取 Android 16 QPR3,然后将其连接到外部显示器,即可立即开始测试您的应用!
不妨深入了解有关多显示屏支持和窗口管理的更新文档,详细了解如何实现这些最佳实践。
反馈
在我们不断改进外接显示器桌面体验的过程中,您的反馈至关重要。您可以通过我们的官方反馈渠道分享您的想法并报告任何问题。
我们一直致力于让 Android 成为一个多功能平台,能够适应用户与应用和设备互动的多种方式。对关联显示屏支持的改进是朝着这个方向迈出的又一步,我们认为您的用户会喜欢您打造的桌面体验!
*注意:撰写本文时,Pixel 8、9、10 系列和各种三星设备(包括 S26、Fold7、Flip7 和 Tab S11)均支持连接的显示屏。
-
产品新闻我们很高兴地宣布,Jetpack WindowManager 1.5.0 现已是稳定版! 此版本在 WindowManager 的强大自适应功能基础上进行了改进,让您能够更轻松地创建精美且自适应的界面,在各种尺寸的屏幕上都能呈现出色的显示效果。
Francesco Romano • 阅读用时:2 分钟 -
产品新闻作为 Android 开发者,您在选择用于应用开发的智能体、大语言模型、工具和命令行界面 (CLI) 时有很多选择。我们的目标是帮助您构建美观优质的 Android 应用,无论您选择以何种方式构建。
Simona Milanovic • 阅读用时:4 分钟 -
产品新闻在 Google Play 上,我们一直在不断扩展订阅平台,以帮助您促进业务增长、适应新的业务模式,并满足用户的需求。
Sheenam Mittal • 阅读用时:4 分钟
每周通过电子邮件接收最新的 Android 开发洞见。