【鸿蒙性能优化】横竖屏切换开发实践

实现视频播窗页面的横竖屏转换,用户可以切换到全屏播放场景。

Figure1横竖屏切换示意

整体开发基本流程

以进入全屏为例,开发过程需要有以下关注点:

1、如果有模态框,需要关闭模态框

2、页面实现窗口旋转和全屏逻辑

3、隐藏播控相关按钮内容

图1进入横屏基本流程

在触发旋转的按钮上,触发对应事件,并可以采用EventHub.emit发送对应事件触发相应事件。这里主要介绍进入全屏的逻辑。

@Builder
RotationButton() {
  Column() {
    Image($r('app.media.ic_rotate'))
      .width(22).height(22)
  }
  ...
  .onClick(() => {
    this.context.eventHub.emit(DATA_EVENT_LIST.CLOSE_BIND_SHEET);
    this.context.eventHub.emit(PLAY_EVENT_LIST.ENTRY_FULL);
    this.closeMenu();
  })
}
进入全屏逻辑
1、实现窗口旋转

主要逻辑包括:(1)获取当前的方向属性值 (2)调用窗口管理的接口设置想要的旋转方向 (3)隐藏状态栏

执行进入全屏时首先需要通过display获取当前的显示方向,并根据当前显示方向,执行对应的屏幕旋转逻辑。

import { display , window } from '@kit.ArkUI';

// 通过display的接口获取方向属性值,display中的方向与window中的方向相同名称,值相差1
const orientation = display.getDefaultDisplaySync().orientation + 1;
// 以直板机为例设置旋转方向
if (orientation === window.Orientation.PORTRAIT) {
  // 竖屏模式切全屏需要转屏,横屏模式切换全屏不需要转屏
  this.setOrientation(window.Orientation.LANDSCAPE_INVERTED)
} else if (orientation === window.Orientation.PORTRAIT_INVERTED) {
  this.setOrientation(window.Orientation.LANDSCAPE)
}
// 设置屏幕旋转方向
setOrientation(orientation: number) {
  Log.info(TAG, `[setOrientation]orientation: ${orientation}`);
  WindowAbility.setWindowOrientation(WindowAbility.getWindowStage(), this.context, orientation)
}
// 隐藏状态栏等业务处理……
hideSystemBar() {
  WindowUtil.hideSystemBar(WindowUtil.getWindowStage())
}

具体的实现逻辑在windowUtil中,在调用屏幕旋转方向时,可以通过windowStage拿到对应的window实例,并设置旋转setPreferredOrientation。

import { window } from '@kit.ArkUI';

export class WindowUtil {
  private static windowStage: window.WindowStage;

  static getWindowStage() {
    return WindowUtil.windowStage
  }

  static setWindowStage(windowStage: window.WindowStage): void {
    WindowUtil.windowStage = windowStage;
  }

  /*
    * 设置横竖屏
    * @Params orientation: 旋转方向
    */
  static setWindowOrientation(windowStage: window.WindowStage, orientation: number): void {
    windowStage.getMainWindow((error, win: window.Window) => {
      win.setPreferredOrientation(orientation).then(
<think>嗯,用户询问的是鸿蒙系统中音视频项目是否支持横竖屏切换及其实现方法。这是一个技术问题,需要结合鸿蒙系统的特性和开发实践来回答。首先确认鸿蒙系统对横竖屏切换的支持情况:根据引用内容[1]和[3],鸿蒙系统确实支持横竖屏切换功能,特别是针对音视频项目。引用[1]提到可以针对单独页面设置窗口方向,引用[3]则直接展示了视频横竖屏切换的示例代码。关于实现方法,需要从三个层面来说明:1.配置层面:在config.json中声明屏幕方向支持,如portrait/landscape等。这是基础配置。2.窗口控制层面:使用WindowStage的setPreferredOrientation方法动态改变方向,如引用[1]所述。这里要注意不同页面的差异化需求。3.UI适配层面:引用[2]展示了关键代码示例,包括监听窗口尺寸变化、计算宽高比、更新布局等。特别要注意全屏模式下的宽高计算和状态栏处理。还要考虑特殊功能实现,如引用[3]提到的屏幕旋转锁定功能,这需要结合系统设置和自定义控制逻辑。最后准备补充两个常见问题:如何处理旋转时的数据保存?如何优化切换性能?这些都是开发者实际会遇到的问题。在回答中会保持技术细节的准确性,避免直接复制引用内容,而是用自己的语言重新组织,确保逻辑清晰。同时会提供具体代码片段增强实用性,比如展示窗口方向设置的典型代码和尺寸变化监听的关键逻辑。</think>鸿蒙系统完全支持音视频项目的横竖屏切换,实现涉及配置声明、窗口控制、UI适配三个核心层面,以下是具体方案: --- ### **一、支持情况** 1. **系统级支持** HarmonyOS 提供原生窗口方向管理 API,可强制锁定或动态切换横屏(`window.Orientation.LANDSCAPE`)、竖屏(`window.Orientation.PORTRAIT`)等方向[^1]。 2. **组件级适配** 视频播放组件(如`<VideoPlayer>`)支持自动旋转渲染,结合布局响应式设计可实现无缝切换[^3]。 --- ### **二、实现方法** #### **1. 全局配置(config.json)** ```json "abilities": [ { "name": "EntryAbility", "orientation": "unspecified", // 允许横竖屏切换 "supportScreenOrientation": ["portrait", "landscape"] // 声明支持的屏幕方向 } ] ``` #### **2. 动态控制窗口方向(关键代码)** ```typescript // 获取窗口实例 const windowClass = window.getLastWindow(this.context); // 强制横屏(视频全屏场景) windowClass.setPreferredOrientation(window.Orientation.LANDSCAPE, (err) => { if (err) { console.error('横屏切换失败'); return; } // 横屏成功,更新UI布局 updateVideoLayout(); }); // 恢复竖屏 windowClass.setPreferredOrientation(window.Orientation.PORTRAIT); ``` #### **3. UI布局自适应(核心逻辑)** ```typescript // 监听窗口尺寸变化(引用自示例[^2]) windowClass.on('windowSizeChange', (size: window.Size) => { const viewWidth = px2vp(size.width); const viewHeight = px2vp(size.height); if (isFullScreen) { // 全屏模式:视频占满窗口 videoComponent.width = viewWidth; videoComponent.height = viewHeight; } else { // 竖屏模式:按比例计算视频区域 const aspectRatio = 16 / 9; videoComponent.height = viewWidth * aspectRatio; } }); ``` #### **4. 旋转锁定功能(交互增强)** ```typescript // 绑定锁定按钮事件(引用自示例[^3]) lockButton.onClick(() => { if (isRotationLocked) { // 解锁:允许随屏幕旋转 windowClass.setPreferredOrientation(window.Orientation.AUTO); } else { // 锁定:固定当前方向 const currentOrientation = windowClass.getProperties().orientation; windowClass.setPreferredOrientation(currentOrientation); } }); ``` --- ### **三、注意事项** 1. **状态栏处理** 横屏时需隐藏状态栏:`windowClass.setWindowSystemBarEnable(['status']).disable()` 2. **数据持久化** 使用`AppStorage`保存播放进度,避免旋转时数据丢失: ```typescript AppStorage.SetOrCreate<number>('currentPosition', 0); videoPlayer.onPause(() => { AppStorage.Set<number>('currentPosition', videoPlayer.currentTime); }); ``` 3. **性能优化** - 减少布局重计算:使用`Flex`弹性布局替代固定尺寸 - 复用组件:避免重复创建视频播放器实例[^2] --- ### **相关问题** 1. 横竖屏切换时如何保持视频播放不中断? 2. 鸿蒙系统如何处理横屏状态下的键盘弹出事件? 3. 多设备适配时(手机/平板),横竖屏布局如何统一管理? [^1]: 鸿蒙窗口方向管理文档 [^2]: 【鸿蒙性能优化横竖屏切换开发实践 [^3]: HarmonyOS Next视频横竖屏切换示例
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值