作者 / Android 团队
近年来,包括大型可折叠设备、平板电脑以及 Chromebook 等大屏 Android 设备的数量与日俱增。确保应用可以在大屏设备上为用户提供无缝体验比以往任何时候都更加重要。例如,用户希望应用能够更充分利用这些设备的更大屏幕空间。我们发现,如果应用能够支持大屏设备,便可以在这些设备上实现更出色的业务指标。
- 在这些设备上实现更出色的业务指标
https://developer.android.google.cn/large-screens/stories
这些设备还可以在不同地方以及不同的方式来使用,而不是通常预想的手机形式。例如,可折叠设备可在桌面模式下使用,用户可能离桌面显示器有一定距离,并且可以搭配鼠标和键盘来使用大屏设备。
但伴随着这些新变化,也出现了一些需要我们注意的新问题。例如:
-
当用户在平板电脑上使用应用时,是否可以通过双手来便捷的触到最重要的控件?
-
用户能否通过键盘和鼠标使用应用的各项功能?
-
无论设备如何放置,应用相机预览的方向能否与设备屏幕方向一致?
大屏应用设计和应用质量
定义什么是出色的大屏应用设计和应用质量可能很难,因为不同的应用可能会在不同的方面拥有卓越表现。您最了解自己的产品,因此请在大屏设备上亲自使用您的应用并思考如何提供最佳体验。如果您无法使用大屏设备,可以尝试在可折叠设备、桌面设备或平板电脑的虚拟设备中选择其一。
Google 在您的整个开发过程中提供资源,有助于您优化应用。如果您正在寻找设计指南,可以参阅我们精心编制的《大屏设备 Material Design 指南》等设计资源,以及可直接使用的组合布局 (如规范化布局等)。您还可以从大屏设备图库中汲取灵感,该图库提供许多不同应用的优秀示例。如果您希望通过结构化方式提高大屏应用的质量,可以参阅《大屏应用质量指南》。该指南提供直观的核对清单和一系列测试,可帮助您的应用在大屏设备上获得精彩表现。
- 大屏设备 Material Design 指南
https://material.io/blog/material-design-for-large-screens - 规范化布局
https://m3.material.io/foundations/layout/canonical-layouts/overview - 大屏设备图库
https://developer.android.google.cn/large-screens/gallery - 大屏应用质量指南
https://developer.android.google.cn/docs/quality-guidelines/large-screen-app-quality
针对大屏设备进行优化的注意事项
无论您是否已经开发出了精美的大屏应用,我们都希望重点介绍一些实用建议,以及在针对大屏设备优化应用时要避免的常见错误。
🙅 错误做法:假设应用享有对资源的专属访问权限
-
不要假设您的应用享有对相机等硬件资源的专属访问权限。通常情况下,大屏设备上会有多款应用同时处于活跃状态,其他应用也可能会尝试访问相同的资源。
-
因此,您应该测试您的应用与其他应用一起工作时的表现。永远不要假设某一资源在任意给定时间均可使用。
-
对相机等硬件资源的专属访问权限
https://developer.android.google.cn/training/camera2/camera-preview#exclusive_resources
🙆 正确做法: 妥善处理硬件访问权限
-
在尝试使用相机等硬件资源之前,您需要先检查此类资源。请记住,硬件外设可以随时通过 USB 添加和移除
-
如果应用在运行时无法访问给定资源,可以妥善处理失败的情况
try {
// Attempt to use the camera
...
} catch (e: CameraAccessException) {
e.message?.let { Log.e(TAG, it) }
// Fail gracefully if the camera isn't currently available
}
}
🙆 正确做法: 对生命周期事件做出恰当的响应
- 在 onPause() 期间,应用可能仍然对用户可见,特别是当屏幕上有多款应用更是如此。因此,在调用 onStop() 之前,您需要保持媒体播放和界面处于活跃状态。
🙅错误做法:在 onPause() 期间停止应用界面
override fun onPause() {
//DON'T clean up resources here.
//Your app can still be visible.
super.onPause()
}
🙅 错误做法: 依靠 "isTablet" 等设备类型布尔值。
- 在过去,应用的常用模式是利用屏幕宽度以创建类似 "isTablet" 这样的布尔值,从而根据运行应用的设备类型做出调整,但这种方法很不可靠。应用需要使用代理来确定设备类型是这种方法的核心问题,而此类代理容易出错。例如,应用在启动时检测到大显示屏,因此确定该设备是平板电脑。但是,如果应用为了不占据全屏而调整其窗口大小,则可能会出现异常。即使您使用的设备类型布尔值可以响应配置更改,在展开可折叠设备的情况下也会影响用户体验,因为在其他配置发生更改 (如重新折叠设备) 之前,该布尔值无法返回。
🙆 正确做法:尽量采用合适的方法取代当前使用设备类型布尔值的方法
查询与要完成的任务所需设备相关的信息。例如:
- 如果您使用设备类型布尔值来调整布局,可以改为使用 WindowSizeClass。该内容库同时支持视图和 Jetpack Compose,以便您能够简单明确地根据预定义断点调整界面。
// androidx.compose.material3.windowsizeclass.WindowSizeClass
class MainActivity : ComponentActivity() {
…
setContent {
val windowSizeClass = calculateWindowSizeClass(this)
WindowSizeClassDisplay(windowSizeClass)
}
@Composable
fun WindowSizeClassDisplay(windowSizeClass : WindowSizeClass) {
when (windowSizeClass.widthSizeClass)
{
WindowWidthSizeClass.Compact -> { compactLayout() }
WindowWidthSizeClass.Medium -> { mediumLayout() }
WindowWidthSizeClass.Expanded -> { expandedLayout() }
}
}
-
如果您使用 isTablet 来更改面向用户的字符串 (如 "您的平板电脑"),那么您可能不需要更多信息便可以轻松解决此问题。您只需使用诸如 "您的 Android 设备" 等更通用的措辞即可。
-
如果您使用设备类型布尔值来预测电话、蓝牙等硬件功能或资源是否存在,在尝试使用所需功能之前,您可以在运行时直接检查其是否可用,如果功能不可用,则需要妥善处理失败的情况。这种基于功能的方法可确保应用能够恰当地响应可连接或移除的外设。此外,这种方法还可以避免某种功能即使受设备支持,也依然缺失的情况。
val packageManager: PackageManager = context.packageManager
val hasTelephony =
packageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)
🙆 正确做法:尽可能使用 Jetpack CameraX
- 显示相机预览可能极为复杂,这涉及到屏幕方向、宽高比等。在您使用 Jetpack CameraX 时,该库将为您处理尽可能多的细节:
https://developer.android.google.cn/training/camerax
🙅 错误做法: 假设相机预览的方向会与设备屏幕方向保持一致
-
在应用中实现相机预览时,需要考虑几种方向: 自然屏幕方向、设备屏幕方向和显示屏幕方向。如要正确实现相机预览,您需要考虑这几种方向,并随着设备条件的变化做出调整。
-
考虑几种方向
https://chromeos.dev/en/android/camera-orientation#all-about-orientations
🙅 错误做法: 假设宽高比是静态的
-
很多原因都可能导致应用可用窗口的宽高比发生变化。您需要确保相机预览应能够适应不断变化的宽高比。
-
应用可用窗口的宽高比发生变化
https://developer.android.google.cn/training/camera2/camera-preview#aspect_ratio
🙆 正确做法 : 正确声明硬件功能要求
- 在声明应用的功能要求时,请参阅《针对大屏设备的实战宝典》中的指南。为了确保您没有不必要地限制应用的受众群体,您需要使用适用于您应用的最详尽的清单条目。
<uses-feature android:name="android.hardware.camera.any" android:required="false" />
<uses-feature android:name="android.hardware.camera" android:required="false" />
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false" />
<uses-feature android:name="android.hardware.camera.flash" android:required="false" />
🙅错误做法: 假设窗口边衬区是静态的
- 大屏设备的屏幕经常变化,包括其 WindowInsets。因此,请勿只在应用启动时才检查边衬区,而且从不进行更改。
🙆 正确做法: 使用面向视图的 WindowInsetsListener API
- 当边衬区发生变化时,WindowInsetsListener API 会通知应用
ViewCompat.setOnApplyWindowInsetsListener(view) { view, windowInsets ->
val insets = windowInsets.getInsets(
WindowInsetsCompat.Type.systemBars())
view.updateLayoutParams<MarginLayoutParams>(
leftMargin = insets.left,
bottomMargin = insets.bottom,
rightMargin = insets.right,
)
WindowInsetsCompat.CONSUMED
}
🙆 正确做法: 在 Jetpack Compose 中使用 windowInsetsPadding Modifier
-
windowInsetsPadding Modifier 会根据给定的窗口边衬区类型动态填充。此外,该 Modifier 的多个实例可以相互通信,以避免添加重复的填充,而且这些实例会自动进行动画处理。
-
windowInsetsPadding Modifier
https://youtu.be/mlL6H-s0nF0
🙅 错误做法: 假设设备配备触摸屏**
- 越来越多的用户开始借助鼠标和键盘来使用 Android 应用,但有时您的应用可能无法提供触摸支持,例如当该应用在连接的显示器上显示时。您需要确保应用的所有功能都支持基本的鼠标或触控板互动:
https://www.youtube.com/watch?v=ucaSqyfpPas
🙆 正确做法: 在大屏设备上测试应用**
-
为了确保您的应用在大屏设备上拥有出色体验,最重要的是要亲自测试应用。我们为您准备好了一个严格测试计划——大屏设备兼容性测试,欢迎您即刻尝试。
🙆 正确做法: 充分利用 Android Studio 中的大屏设备工具
-
Android Studio 提供了可在开发过程中使用的工具,帮助您更轻松地针对大屏设备优化应用。例如,您可以使用 MultiPreview 注释以同时在多种条件下直观地查看应用。此外,Android 虚拟设备管理器还提供多种平板电脑、桌面设备和可折叠设备的 Android 虚拟设备 (AVD),以便您即刻在大屏设备上测试应用。
-
MultiPreview 注释
https://developer.android.google.cn/jetpack/compose/tooling/previews#preview-multipreview -
Android 虚拟设备管理器
https://developer.android.google.cn/studio/run/managing-avds
Google I/O 大会精彩回顾
希望这些建议可作为您针对大屏设备优化应用时的良好起点。在今年的 Google I/O 大会上,我们发布了 Google 的最新资讯和创新。
版权声明
禁止一切形式的转载-禁止商用-禁止衍生 申请授权