鸿蒙5.0项目开发——横竖屏切换开发

发布于:2025-06-04 ⋅ 阅读:(29) ⋅ 点赞:(0)

横竖屏切换开发

【高心星出品】

横竖屏切换功能即实现应用内既支持竖屏显示也支持横屏显示的效果。对于应用内不同页面显示方向不同的情况,需要在应用逻辑中,动态修改窗口方向,来实现该效果,例如包含视频播放功能的应用,首页内容是采用竖屏方式,而视频详情页则采用横屏方式展示。

运行效果

在这里插入图片描述

窗口旋转

目前在HarmonyOS系统中,窗口的旋转形态包括以下四种,窗口的状态对应真机实际状态如下:

在这里插入图片描述

有两种设置窗口旋转策略的方式:

通过module.json5文件中“orientation”字段进行设置

在代码中通过调用窗口window的setPreferredOrientation方法进行设置

这两种方式触发设置旋转的时机不同,总的来说,module.json5文件中的字段在窗口启动时就会生效,对于应用启动时就需要设置横屏或者竖屏的应用,需要进行配置。而setPreferredOrientation是在调用该方法时进行窗口方向的设置,用于在应用启动之后,还需要改变显示方向的场景。

配置module.json5的orientation字段

此字段配置的是应用启动时的窗口显示状态,对于开屏时就需要以默认的横屏或者竖屏方式显示,需要在此字段进行相应的配置:


{
  "module": {
    // ...
    "abilities": [
      {
        "name": "EntryAbility",
        // ...
        "orientation": "portrait"
      }
    ]
  }
}

其支持的参数可以参考module.json5配置项中orientation字段相关配置的orientation字段说明:

根据应用默认的旋转行为进行相应的配置:

  • 如果应用是竖屏应用,建议配置portrait为默认旋转策略。

  • 如果应用是横屏应用,例如游戏类应用,进入游戏时,默认就是横屏,此时有两种情况:

    一、仅支持横屏,建议配置landscape为默认旋转策略。

    二、支持在横屏和反向横屏中切换,建议设置为auto_rotation_landscape。

  • 如果应用为可旋转应用,建议应用配置auto_rotation_restricted为默认旋转策略。

  • 如果一个应用,在直板机和折叠机折叠态是竖屏应用,在平板和折叠机展开态默认是可旋转应用,推荐配置follow_desktop为默认旋转策略。

调用窗口的setPreferredOrientation方法

对于需要进入应用后,修改应用窗口显示横竖屏状态的情况下,可以调用setPreferredOrientation方法进行设置,典型场景如一些视频类应用、图片类应用等。

在这里插入图片描述

此类应用在进入时为竖屏,而在视频播放页面可以显示为横屏,则需要支持用户临时修改窗口方向。由于setPreferredOrientation方法调用的是窗口的显示方向,是整个应用窗口级别都发生了旋转,窗口将一直保持最后一次设置窗口方向的效果,即使发生页面跳转等行为窗口方向也不会发生变化。

案例代码解析

本项目Entry模块中有两个ability,入口ability为EntryAbility1加载的Index1页面,该页面只有一个按钮,点击跳转到EntryAbility敞口,该窗口加载为竖屏展示,并加载了Index页面。

Index1页面代码:
import { common, Want } from '@kit.AbilityKit';

@Entry
@Component
struct Index1 {
  @State message: string = 'Hello World';
  private context:common.UIAbilityContext=getContext(this) as common.UIAbilityContext
  build() {
    Column(){
      Button('跳转')
        .width('60%')
        .onClick(()=>{
          let params:Record<string,Object>={
            'from':'EntryAbility1',
            'count':10
          }
          let want:Want={
            moduleName:'entry',
            bundleName:'com.gxx.orientationdemo',
            abilityName:'EntryAbility',
            parameters:params
          }
          //跳转到Entryability
          this.context.startAbility(want,(err,data)=>{
            if(err)
            {
              console.error('gxxt ',JSON.stringify(err.message))
              return
            }
            console.log('gxxt ',JSON.stringify(data))
          })
        })
    }
    .height('100%')
    .width('100%')
    .justifyContent(FlexAlign.Center)
  }
}
EntryAbility在module.json5的配置信息:
{
  "name": "EntryAbility",
  "srcEntry": "./ets/entryability/EntryAbility.ets",
  "description": "$string:EntryAbility_desc",
  "icon": "$media:layered_image",
  "label": "$string:EntryAbility_label",
  "startWindowIcon": "$media:startIcon",
  "startWindowBackground": "$color:start_window_background",
      //默认为竖屏展示
  "orientation": "portrait",
  "exported": true,
},
Index页面的代码信息:
import { common } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';

@Entry
@Component
struct Index {
  private context:common.UIAbilityContext=getContext(this) as common.UIAbilityContext
  //默认为竖屏
  @State orientation:string='portrait'
  aboutToAppear(): void {
    this.context.windowStage.getMainWindowSync().on('windowSizeChange',(size)=>{
      let wid=px2vp(size.width)
      let hei=px2vp(size.height)
      if(wid>hei)
      {//横屏
        this.orientation='landscape'
      }else{
        //竖屏
        this.orientation='portrait'
      }
    })
  }
  build() {
    // 通过不同的水平 展示不同的界面
    if(this.orientation==='portrait') {
        this.gencontent()
    }else{
        this.gencontent1()
    }
  }
  @Builder
  gencontent() {
    Column({ space: 20 }) {
      Text('块1')
        .width(200)
        .height(200)
        .backgroundColor(Color.Red)
        .textAlign(TextAlign.Center)
        .fontColor(Color.White)
        .fontWeight(FontWeight.Bolder)
        .fontSize(30)
      Text('块2')
        .width(200)
        .height(200)
        .backgroundColor(Color.Blue)
        .textAlign(TextAlign.Center)
        .fontColor(Color.White)
        .fontWeight(FontWeight.Bolder)
        .fontSize(30)
      Button('切换屏幕')
        .width('50%')
        .onClick(() => {
          let window1 = this.context.windowStage.getMainWindowSync()
          window1.setPreferredOrientation(this.orientation === 'portrait' ? window.Orientation.LANDSCAPE :
          window.Orientation.PORTRAIT)
        })
    }
    .width('100%')
    .height('100%')
  }

  @Builder
  gencontent1() {
    Column({space:20}) {
      Row({space:20}) {
        Text('块1')
          .width(200)
          .height(200)
          .backgroundColor(Color.Red)
          .textAlign(TextAlign.Center)
          .fontColor(Color.White)
          .fontWeight(FontWeight.Bolder)
          .fontSize(30)
        Text('块2')
          .width(200)
          .height(200)
          .backgroundColor(Color.Blue)
          .textAlign(TextAlign.Center)
          .fontColor(Color.White)
          .fontWeight(FontWeight.Bolder)
          .fontSize(30)
      }
      .width('100%')
      .justifyContent(FlexAlign.Center)

      Button('切换屏幕')
        .width('50%')
        .onClick(() => {
          let window1 = this.context.windowStage.getMainWindowSync()
          window1.setPreferredOrientation(this.orientation === 'portrait' ? window.Orientation.LANDSCAPE :
          window.Orientation.PORTRAIT)
        })
    }.width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
  }
}


网站公告

今日签到

点亮在社区的每一天
去签到