我们的视频应用想在展开态自动横屏(宽屏更适合看视频)。在 module.json5 里配了 orientation,但真机上怎么转都不横。
是不是折叠屏有额外的限制?
折叠屏的旋转逻辑和普通手机不同:展开态在大屏下默认遵循"设备物理方向",而且部分系统版本会对大屏应用的旋转做限制。排查这几项:
① 配置项要在 ability 上,且值要选对
{
"module": {
"abilities": [
{
"name": "EntryAbility",
"orientation": "auto_rotation"
}
]
}
}
| 值 | 含义 |
|---|---|
unspecified | 跟随系统(默认) |
landscape | 强制横屏 |
portrait | 强制竖屏 |
auto_rotation | 跟随传感器(推荐) |
landscape_inverted | 反向横屏 |
② 运行时动态设置
import { window } from '@kit.ArkUI'
const win = await window.getLastWindow(context)
// 进入视频页面:允许自动旋转
win.setPreferredOrientation(window.Orientation.AUTO_ROTATION)
// 退出:恢复竖屏
win.setPreferredOrientation(window.Orientation.PORTRAIT)
③ 系统级的两个限制(这就是你"怎么转都不横"的原因)
| 限制 | 说明 |
|---|---|
| 系统"自动旋转"开关关闭 | 用户在快捷开关里关了自动旋转,应用无法绕过(除非法配置 landscape 强制) |
| 折叠态外屏锁定竖屏 | 折叠屏的外屏通常锁定竖屏,展开态才允许旋转 |
④ 最佳实践
-
不要"进入页面就强制横屏",用户会觉得很突兀。视频应用的正确做法是播放时允许旋转,非播放状态跟随系统;
-
折叠屏展开态如果已经是宽比例(接近方形),优先做"宽屏竖屏布局"而不是强制横屏,用户不用转手机体验更好;
-
旋转会导致页面重建(除非配置了
configChanges),如果强制横屏,必须保证旋转后状态不丢(参考 Q54)。
⑤ 调试钩子:真机上用开发者选项里的"强制横屏/竖屏"验证,别只依赖传感器实际旋转,模拟器上旋转行为可能和真机不一致。
要确认 orientation 配在目标 UIAbility 下,再检查运行时有没有覆盖设置。
视频全屏可对主窗口调用 setPreferredOrientation(LANDSCAPE),退出时恢复原策略。非主窗口、自由窗口等场景可能不生效且不报错。展开不等于横屏,布局仍要按实际窗口宽高适配,并记录机型、系统版本定位差异。
折叠屏"展开态强制横屏"的需求要先拆开:折叠屏展开后的内屏本身就是横屏比例,系统显示的"方向"概念和你想要的"内容横排"不是一回事。处理方案:
一、展开态不需要强制旋转:折叠屏机型展开后的内屏分辨率本身就是宽屏,应用窗口自动获得宽屏布局空间——你要的"横屏布局"直接通过断点/窗口尺寸适配实现,不需要设置屏幕方向。如果你的页面还是竖排布局,是断点没覆盖到展开态的宽度档位,补断点而不是转方向。
二、真要控制方向的场景(如视频全屏):用 window 的 setPreferredOrientation——支持 LANDSCAPE、LOCKED 等枚举。但折叠屏上系统可能锁定方向策略(跟随折叠状态),setPreferredOrientation 会被忽略或冲突,需要监听 foldStatusChange 在回调里按折叠状态设置方向,且做好设置失败的兜底。
三、推荐的适配策略:折叠态(外屏竖屏)用竖版布局;展开态(内屏宽屏)用双栏/横版布局——这比强制横屏体验好得多,也是折叠屏适配的推荐做法(主流应用都是这么做的:展开态左列表右详情)。
四、一个常见的坑:展开态页面重建时,如果代码里有按竖屏写的硬编码(固定高度、竖排 Flex),宽屏下就乱——这也是你看到"系统不让我旋转"的观感来源之一:系统给的窗口就是宽的,但你的布局还是竖的。
一句话收束:折叠屏展开态要的是"宽屏布局适配"不是"强制旋转"——补展开态断点的双栏布局,真需要方向控制用 setPreferredOrientation 配合 foldStatusChange 监听。

