限制应用在手机上的屏幕方向,但不限制其在大屏设备上的屏幕方向

2 星级图标

您的应用在手机上的纵向模式下效果好,因此您将应用限制为仅限纵向显示。但是您发现,对于大屏设备而言,该应用在横向模式下或许可以实现更多优势。

如何同时兼顾两种场景?也就是说,如何让应用在小屏设备上仅可纵向显示,但在大屏设备上也可横向显示?

最佳做法

出色的应用会遵循用户偏好设置,例如设备屏幕方向设置。

自适应应用质量指南建议应用支持所有设备配置,包括纵向和横向屏幕方向、多窗口模式以及可折叠设备的折叠和展开状态。应用应针对不同的配置优化布局和界面,并且在配置发生更改时应保存及恢复状态。

此方案是一种临时性措施 - 提供些许的大屏幕支持。在您能够改进应用,使其针对所有设备配置提供全面支持之前,可以权且使用此方案。

所需要素

  • screenOrientation:应用清单设置,让您可以指定应用如何响应设备屏幕方向的变化
  • Activity#setRequestedOrientation():用于在运行时更改应用屏幕方向的方法
  • LocalConfiguration:可组合的本地提供程序,用于公开当前设备的 Configuration,以便您读取以 DP 为单位的屏幕尺寸。
  • LaunchedEffect:用于编写在键发生更改时(在本例中为配置发生更改时)运行代码块的 Compose 副作用 API。

步骤

在应用清单中让应用默认能够响应屏幕方向变化。 然后,在运行时,使用 Jetpack Compose 在紧凑型屏幕(手机)上动态限制为竖屏方向,同时允许在大屏设备上使用所有屏幕方向。

1. 在应用清单中指定屏幕方向设置

您可以避免声明应用清单的 screenOrientation 元素(在这种情况下,屏幕方向默认为 unspecified),或将屏幕方向设为 fullUser。如果用户没有锁定基于传感器的旋转,您的应用将支持所有设备屏幕方向。

<activity
    android:name=".MyActivity"
    android:screenOrientation="fullUser">

使用 unspecifiedfullUser 之间的区别虽然微不足道,但很重要。如果您未声明 screenOrientation 值,系统会选择屏幕方向,并且系统用于定义屏幕方向的政策可能会因设备而异。另一方面,指定 fullUser 更符合用户为设备定义的行为:如果用户已锁定基于传感器的旋转,应用会遵循用户偏好设置;否则,系统允许使用四种可能的屏幕方向(竖屏、横屏、反向竖屏或反向横屏)。请参阅 android:screenOrientation

2. 在 Compose 中动态限制屏幕方向

在 Jetpack Compose 中,您可以从 LocalConfiguration.current 中以响应式方式读取当前屏幕尺寸(以 DP 为单位),并使用 LaunchedEffect 在配置发生变化时更新 Activity 的屏幕方向。

如果屏幕宽度或高度小于 600dp(对应于手机的紧凑型屏幕尺寸分界点),则将屏幕方向限制为纵向。否则,允许系统根据用户偏好设置(unspecifiedfullUser)旋转应用。

以下是完整的、可编译的实现:

val configuration = LocalConfiguration.current
val context = LocalActivity.current

LaunchedEffect(configuration) {
    val activity = context ?: return@LaunchedEffect
    // Determine if screen is compact (phone-sized) in either width or height
    val isCompact = configuration.screenWidthDp < 600 || configuration.screenHeightDp < 600
    activity.requestedOrientation = if (isCompact) {
        ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
    } else {
        ActivityInfo.SCREEN_ORIENTATION_FULL_USER
    }
}

通过在 LaunchedEffect(configuration) 块内添加逻辑,您可以在应用配置发生变化时(例如 activity 调整大小、在不同显示屏之间移动,或者可折叠设备折叠或展开时)主动替换屏幕方向设置。

如需详细了解何时配置会更改以及何时会导致 activity 重新创建,请参阅处理配置更改

结果

现在,在小屏设备上,无论设备如何旋转,应用应该会始终保持纵向模式。在大屏设备上,该应用应支持横向模式和纵向模式。

其他资源

如果您希望升级应用以使其始终支持所有设备配置,并需要这方面的帮助,请参阅以下内容: