【HarmonyOS 5】鸿蒙应用代码控制横竖屏切换,自动切换横竖屏,监听横竖屏以及注意事项
一、前言
在移动应用开发过程中,横竖屏切换(Orientation) 是一个非常常见的需求。
例如:
- 视频播放器全屏
- 图片浏览
- 地图导航
- 游戏
- PDF阅读器
- 摄像头
- 平板应用
HarmonyOS 5 提供了完整的窗口方向控制能力,可以:
✔ 指定页面固定竖屏
✔ 指定页面固定横屏
✔ 根据重力自动旋转
✔ 代码动态切换横竖屏
✔ 获取当前方向
✔ 监听页面方向变化
✔ 支持折叠屏和平板
本文将全面讲解 HarmonyOS 中屏幕方向控制的所有知识。
二、屏幕方向(Orientation)介绍
HarmonyOS 中方向主要包括:
| 方向 | 说明 |
|---|---|
| Portrait | 竖屏 |
| Landscape | 横屏 |
| Auto Rotation | 自动旋转 |
| Reverse Portrait | 倒立竖屏 |
| Reverse Landscape | 反向横屏 |
开发中真正常用的是:
竖屏
横屏
自动旋转
三、HarmonyOS 屏幕方向控制方式
HarmonyOS 提供两种控制方式:
方式一:配置文件固定方向
适用于:
- 登录页
- Splash
- 游戏
例如:
module.json5
配置:
{
"abilities": [
{
"orientation": "portrait"
}
]
}
支持:
portrait
landscape
auto_rotation
优点:
- 简单
- 全局生效
缺点:
不能动态修改。
方式二:代码动态修改(推荐)
官方推荐:
window.setPreferredOrientation()
几乎所有视频播放器都采用这种方案。
四、Window对象获取
动态切换方向,需要先获取 Window。
HarmonyOS Stage模型:
import { window } from '@kit.ArkUI'
let win = await window.getLastWindow(getContext())
或者:
window.getLastWindow(getContext())
.then(win=>{
})
Window 是控制:
- 全屏
- 横竖屏
- 状态栏
- 导航栏
的重要对象。
五、PreferredOrientation 枚举详解
HarmonyOS 提供多个方向枚举。
window.Orientation
常见如下:
| 枚举 | 说明 |
|---|---|
| AUTO_ROTATION | 自动旋转 |
| PORTRAIT | 竖屏 |
| LANDSCAPE | 横屏 |
| PORTRAIT_INVERTED | 倒立竖屏 |
| LANDSCAPE_INVERTED | 反向横屏 |
| AUTO_ROTATION_PORTRAIT | 自动但保持竖屏系列 |
| AUTO_ROTATION_LANDSCAPE | 自动但保持横屏系列 |
开发中最常见:
PORTRAIT
LANDSCAPE
AUTO_ROTATION
六、固定竖屏
例如:
import { window } from '@kit.ArkUI'
async function portrait() {
let win = await window.getLastWindow(getContext())
await win.setPreferredOrientation(
window.Orientation.PORTRAIT
)
}
运行效果:
无论手机如何旋转
始终保持竖屏
七、固定横屏
例如:
async function landscape(){
let win = await window.getLastWindow(getContext())
await win.setPreferredOrientation(
window.Orientation.LANDSCAPE
)
}
效果:
进入页面
立即横屏
常用于:
- 视频
- 游戏
八、恢复自动旋转
退出视频播放器:
await win.setPreferredOrientation(
window.Orientation.AUTO_ROTATION
)
即可恢复系统方向。
九、按钮控制横竖屏切换
例如:
import { window } from '@kit.ArkUI'
@Entry
@Component
struct Index {
private win?:window.Window
async aboutToAppear(){
this.win=await window.getLastWindow(getContext())
}
build(){
Column(){
Button("竖屏")
.onClick(async()=>{
await this.win?.setPreferredOrientation(
window.Orientation.PORTRAIT
)
})
Button("横屏")
.margin({top:20})
.onClick(async()=>{
await this.win?.setPreferredOrientation(
window.Orientation.LANDSCAPE
)
})
Button("自动")
.margin({top:20})
.onClick(async()=>{
await this.win?.setPreferredOrientation(
window.Orientation.AUTO_ROTATION
)
})
}
.width("100%")
.height("100%")
.justifyContent(FlexAlign.Center)
}
}
最终效果:
点击按钮
立即切换方向
十、进入页面自动横屏
很多播放器都会:
进入页面
自动横屏
例如:
async aboutToAppear(){
this.win=await window.getLastWindow(getContext())
await this.win?.setPreferredOrientation(
window.Orientation.LANDSCAPE
)
}
十一、退出页面恢复竖屏
推荐:
aboutToDisappear(){
this.win?.setPreferredOrientation(
window.Orientation.PORTRAIT
)
}
或者:
恢复自动:
aboutToDisappear(){
this.win?.setPreferredOrientation(
window.Orientation.AUTO_ROTATION
)
}
这是最推荐的写法。
十二、自动切换横竖屏
自动旋转实际上就是:
AUTO_ROTATION
例如:
await win.setPreferredOrientation(
window.Orientation.AUTO_ROTATION
)
前提:
用户开启:
系统设置
↓
自动旋转
否则不会自动旋转。
十三、如何判断当前方向
获取 Window 后:
let orientation=win.getPreferredOrientation()
返回:
PORTRAIT
LANDSCAPE
AUTO_ROTATION
注意:
这里返回的是:
偏好方向
不是实时重力方向
很多新人容易混淆。
十四、监听横竖屏变化
HarmonyOS 可以监听窗口属性变化。
例如:
win.on('windowSizeChange', (data) => {
console.info(`width=${data.width}`)
console.info(`height=${data.height}`)
})
判断:
if(data.width>data.height){
console.info("横屏")
}else{
console.info("竖屏")
}
这是开发中最常见的方案。
十五、通过宽高判断方向
很多应用直接:
if(width>height){
}
横屏:
宽 > 高
竖屏:
高 > 宽
这是最稳定的方法。
十六、页面响应式布局
建议不要写:
if(PORTRAIT){
}
推荐:
if(width>height){
//横屏布局
}else{
//竖屏布局
}
这样:
- 平板
- 折叠屏
- PC
全部兼容。
十七、视频播放器最佳实践
播放器流程:
点击全屏
↓
切横屏
↓
隐藏状态栏
↓
播放视频
↓
退出全屏
↓
恢复竖屏
代码:
await win.setPreferredOrientation(
window.Orientation.LANDSCAPE
)
退出:
await win.setPreferredOrientation(
window.Orientation.PORTRAIT
)
十八、阅读器最佳实践
例如:
电子书
漫画
进入:
横屏
退出:
恢复
这样阅读体验更好。
十九、地图导航
导航页面:
建议:
AUTO_ROTATION
因为:
用户可能:
- 手机支架横放
- 手持竖屏
自动旋转体验最好。
二十、游戏
游戏:
建议:
LANDSCAPE
固定横屏。
不要:
AUTO_ROTATION
否则游戏会频繁旋转。
二十一、折叠屏注意事项
HarmonyOS NEXT:
折叠屏越来越多。
不要:
固定宽度布局
推荐:
响应式布局
横竖屏切换时:
重新计算:
Grid
List
WaterFlow
布局。
二十二、平板适配
平板:
经常:
自由旋转
建议:
AUTO_ROTATION
不要强制:
PORTRAIT
影响用户体验。
二十三、常见问题
问题一:为什么调用后没有旋转?
原因:
系统:
关闭自动旋转
或者:
页面固定方向。
问题二:为什么方向改变布局没刷新?
因为:
布局没有响应窗口变化。
需要:
监听:
windowSizeChange
重新更新状态。
问题三:为什么视频退出后还是横屏?
原因:
没有恢复:
PORTRAIT
或者:
AUTO_ROTATION
问题四:为什么页面会闪一下?
原因:
方向切换会触发:
Window重新布局
属于正常现象。
二十四、最佳实践总结
推荐遵循以下原则:
| 场景 | 推荐方向 |
|---|---|
| 登录页 | PORTRAIT |
| 首页 | AUTO_ROTATION |
| 视频播放 | LANDSCAPE(全屏时) |
| 图片浏览 | AUTO_ROTATION |
| 地图导航 | AUTO_ROTATION |
| PDF 阅读 | LANDSCAPE 或 AUTO_ROTATION |
| 游戏 | LANDSCAPE |
| 平板应用 | AUTO_ROTATION |
| 折叠屏应用 | AUTO_ROTATION + 响应式布局 |
二十五、完整示例:封装方向管理工具
为了避免在多个页面重复编写方向切换逻辑,可以封装一个工具类:
import { window } from '@kit.ArkUI';
export class OrientationManager {
private static win?: window.Window;
static async init(context: UIContext) {
if (!this.win) {
this.win = await window.getLastWindow(context);
}
}
static async portrait() {
await this.win?.setPreferredOrientation(window.Orientation.PORTRAIT);
}
static async landscape() {
await this.win?.setPreferredOrientation(window.Orientation.LANDSCAPE);
}
static async auto() {
await this.win?.setPreferredOrientation(window.Orientation.AUTO_ROTATION);
}
}
页面中使用:
aboutToAppear() {
OrientationManager.init(getContext());
}
Button("横屏")
.onClick(async () => {
await OrientationManager.landscape();
})
这样可以统一管理应用内的横竖屏切换逻辑,尤其适合播放器、阅读器等多个页面共用的场景。
二十六、总结
HarmonyOS 5 的横竖屏控制主要依赖 Window 提供的方向控制能力。开发中建议遵循以下原则:
- 全局固定方向:通过
module.json5配置,适用于启动页、游戏等固定场景。 - 动态切换方向:通过
Window.setPreferredOrientation()控制,是视频播放器、图片浏览器等场景的首选方案。 - 监听方向变化:优先监听窗口尺寸变化(如
windowSizeChange),通过宽高比判断横竖屏,而不是依赖固定方向枚举。 - 页面生命周期恢复方向:进入页面时根据业务切换方向,退出页面时恢复为竖屏或自动旋转,避免影响其他页面。
- 兼容折叠屏和平板:尽量采用响应式布局,避免依赖固定方向或固定尺寸。
更多推荐



所有评论(0)