【HarmonyOS】ArkTS开发应用的横竖屏切换

文章目录

1、简介

在完成全屏网页嵌套应用开发后,设备方向适配成为提升用户体验的关键环节。本文将深度解析鸿蒙ArkTS框架下静态配置与动态调整两种横竖屏切换方案,结合实际开发场景提供可复用的技术实现。

随着移动端场景多元化,应用需适配手持阅读、平板展示等多形态需求。鸿蒙系统提供双模式支持:

  • 静态配置:通过模块声明实现基础方向锁定
  • 动态调整:运行时感知设备旋转并智能适配

2、静态 --- 横竖屏切换

2.1、效果

可通过修改module.json5中abilities下orientation属性实现横竖屏切换。

2.2、实现原理

标识当前UIAbility组件启动时的方向,支持配置枚举和启动方向资源索引。枚举支持的取值如下:

  • unspecified:未指定方向,由系统自动判断显示方向。

  • landscape:横屏。

  • portrait:竖屏。

  • follow_recent:跟随背景窗口的旋转模式。

  • landscape_inverted:反向横屏。

  • portrait_inverted:反向竖屏。

  • auto_rotation:随传感器旋转。

  • auto_rotation_landscape:传感器横屏旋转,包括横屏和反向横屏。

  • auto_rotation_portrait:传感器竖屏旋转,包括竖屏和反向竖屏。

  • auto_rotation_restricted:传感器开关打开,方向可随传感器旋转。

  • auto_rotation_landscape_restricted:传感器开关打开,方向可随传感器旋转为横屏, 包括横屏和反向横屏。

  • auto_rotation_portrait_restricted:传感器开关打开,方向随可传感器旋转为竖屏, 包括竖屏和反向竖屏。

  • locked:传感器开关关闭,方向锁定。

  • auto_rotation_unspecified:受开关控制和由系统判定的自动旋转模式。

  • follow_desktop:跟随桌面的旋转模式。

配置启动方向的资源索引时,取值为长度不超过255字节的字符串。

启动方向资源索引配置示例:$string:orientation。

2.3、module.json5 源码

按照上述原理,假设我们要直接设置横屏,module.json5 代码如下:

js 复制代码
{
  "module": {
    "name": "entry",
    "type": "entry",
    "description": "$string:module_desc",
    "mainElement": "EntryAbility",
    "deviceTypes": [
      "phone"
    ],
    "deliveryWithInstall": true,
    "installationFree": false,
    "pages": "$profile:main_pages",
    "abilities": [
      {
        "name": "EntryAbility",
        "srcEntry": "./ets/entryability/EntryAbility.ts",
        "description": "$string:EntryAbility_desc",
        "icon": "$media:icon",
        "label": "$string:EntryAbility_label",
        "orientation": "landscape",
        "startWindowIcon": "$media:icon",
        "startWindowBackground": "$color:start_window_background",
        "exported": true,
        "skills": [
          {
            "entities": [
              "entity.system.home"
            ],
            "actions": [
              "action.system.home"
            ]
          }
        ]
      }
    ],
  }
}

3、动态 --- 横竖屏切换

3.1、应用随系统旋转切换横竖屏

应用的页面都会随着手机旋转而发生展示上的切换,而打开时则不会发生旋转行为,此时就需要配置为auto_rotation_restricted。

3.2、setPreferredOrientation 原理配置

在具体需要实现横竖屏切换的页面上,例如视频播放页面支持横屏,但是首页的内容是支持仅竖屏的,那么就需要在进入对应的页面时,采用window窗口提供的设置窗口方向的能力,通过setPreferredOrientation将窗口显示的方向修改为横屏、竖屏的状态。在使用时,需根据应用自身的旋转策略选择相应的参数,可以封装如下方法,进行旋转策略的设置。

具体如下:通过getContext拿到对应的UIAbilityContext,并通过context拿到对应的windowStage实例,然后通过windowStage.getMainWindowSync同步方法拿到对应的窗口实例win,然后调用setPreferredOrientation方法设置窗口方向。

js 复制代码
setOrientation(orientation: number) {
  this.windowClass.setPreferredOrientation(orientation).then(() => {
    console.info('setWindowOrientation: ' + orientation + ' Succeeded.');
  }).catch((err: BusinessError) => {
    console.info('setWindowOrientation: ' + orientation + ' Failed. Cause: ' + JSON.stringify(err));
  });
}

3.3、锁定旋转的情况下,手动设置横屏状态

以视频播放为例,不仅需要可以通过系统控制横竖屏,也支持用户在系统锁定旋转的情况下,手动设置横屏状态,即需要满足以下条件:

js 复制代码
1、应用跟随传感器旋转。
2、受到控制中心的旋转锁定按钮控制。
3、支持用户使用应用时,在页面中临时调用设置方向能力,如点击全屏按钮进行切换。

要实现以上效果,可以使用窗口的能力设置orientation的枚举类型进行相应的旋转,由于要提供临时设置方向的能力,用户在手动点击全屏按钮时,相当于需要手动触发横竖屏切换,如果此时关闭了旋转锁定,那么窗口需要能够跟随传感器一起发生旋转,所以可以使用以下枚举中的能力,临时调用旋转,并让其后续也能支持跟随传感器。

orientation枚举值 枚举数值 效果描述
USER_ROTATION_PORTRAIT 13 调用时临时旋转到竖屏,之后跟随传感器自动旋转,受控制中心的旋转开关控制,且可旋转方向受系统判定。
USER_ROTATION_LANDSCAPE 14 调用时临时旋转到横屏,之后跟随传感器自动旋转,受控制中心的旋转开关控制,且可旋转方向受系统判定。

分析旋转方向:对于视频播放的应用,一般旋转方向不会旋转到反向竖屏(由UX需求决定),即只旋转到竖屏、横屏和反向横屏。并且用户在使用时,点击切换按钮时,根据用户习惯,一般默认是旋转到横屏状态,然后支持跟随传感器旋转到反向横屏。

在需要用户点击的地方,需要根据进入全屏和退出全屏分别执行相应的逻辑,需要使用的方向状态如下:

设置为横屏时,对应窗口方向为横屏状态:this.setOrientation(window.Orientation.USER_ROTATION_LANDSCAPE),例如进入播放页时,进行竖屏 -> 横屏切换;

js 复制代码
Image($r('app.media.icon_zoom_in'))
  // ...
  .onClick(() => {
    if (display.getFoldStatus() === display.FoldStatus.FOLD_STATUS_EXPANDED || display.getFoldStatus() === display.FoldStatus.FOLD_STATUS_HALF_FOLDED) {
      this.isLandscape = true;
    } else {
      this.setOrientation(window.Orientation.USER_ROTATION_LANDSCAPE);
    }
  })

设置为竖屏时,对应窗口方向为竖屏状态:this.setOrientation(window.Orientation.USER_ROTATION_PORTRAIT),例如在返回竖屏状态时,进行横屏 -> 竖屏切换;

js 复制代码
Image($r('app.media.icon_back'))
  // ...
  .onClick(() => {
    // ...
      this.setOrientation(window.Orientation.USER_ROTATION_PORTRAIT);
      // ...
  })

注意!

需要注意的是,由于setPreferredOrientation方法调用改变的是窗口的显示方向,所以如果在进入视频播放页时,手动调用了旋转到横屏,那么在退出时也需要手动调用该接口,使窗口回到之前的竖屏状态。

相关推荐
咖啡の猫15 小时前
Android开发-常用布局
android·gitee
程序员潘Sir15 小时前
鸿蒙应用开发从入门到实战(一):鸿蒙应用开发概述
harmonyos
程序员老刘15 小时前
Google突然“变脸“,2026年要给全球开发者上“紧箍咒“?
android·flutter·客户端
Tans515 小时前
Androidx Lifecycle 源码阅读笔记
android·android jetpack·源码阅读
雨白16 小时前
实现双向滑动的 ScalableImageView(下)
android
峥嵘life16 小时前
Android Studio新版本编译release版本apk实现
android·ide·android studio
studyForMokey18 小时前
【Android 消息机制】Handler
android
敲代码的鱼哇18 小时前
跳转原生系统设置插件 支持安卓/iOS/鸿蒙UTS组件
android·ios·harmonyos
翻滚丷大头鱼18 小时前
android View详解—动画
android
我是好小孩18 小时前
[Android]RecycleView的item用法
android