HarmonyOS 鸿蒙Next中横屏的状态下怎么避开安全区

HarmonyOS 鸿蒙Next中横屏的状态下怎么避开安全区

如图, 我这个页面仅有横屏状态, 这个时候,怎么让左边的显示区域避开挖孔呢,

我的代码:

build() {
    NavDestination() {

      Stack(){

        Image($r("app.media.test"))
          .objectFit(ImageFit.Contain)
          .align(Alignment.Center)

        Row(){
          Column(){
            Text("左边的").fontColor(Color.White)
          }.backgroundColor(Color.Red)
          .expandSafeArea([SafeAreaType.CUTOUT],[SafeAreaEdge.START,SafeAreaEdge.END])

          Column(){
            Text("上").fontColor(Color.White)
            Text("中").fontColor(Color.White).layoutWeight(1)
            Text("下").fontColor(Color.White)
          }
          .layoutWeight(1)

          Column(){
            Text("右边的").fontColor(Color.White)
          }.expandSafeArea([SafeAreaType.CUTOUT],[SafeAreaEdge.START,SafeAreaEdge.END])
        }

      }
      // .width('100%')
      // .height('100%')
    }
    .backgroundColor(Color.Black)
    .hideTitleBar(true)
    .onHidden(() => {

    })

    .onDisAppear(() => {

    })
  }


更多关于HarmonyOS 鸿蒙Next中横屏的状态下怎么避开安全区的实战教程也可以访问 https://www.itying.com/category-93-b0.html

8 回复

鸿蒙系统通过expandSafeArea属性处理CUTOUT类型安全区域,需明确指定避让方向和组件层级关系,楼主代码左右两侧Column组件参数设置顺序错误,好像也没有正确处理横屏方向与安全区域边缘映射关系。

优化了一下试试行不行?

build() {
  NavDestination() {
    Stack() {
      Image($r("app.media.test"))
        .objectFit(ImageFit.Contain)
        .align(Alignment.Center)

      Row() {
        // 左侧避让区域
        Column() {
          Text("左边的").fontColor(Color.White)
        }
        .expandSafeArea([SafeAreaType.CUTOUT], [SafeAreaEdge.START])
        .width('15%')
        .backgroundColor(Color.Red)

        // 中间内容区域
        Column() {
          Text("上").fontColor(Color.White)
          Text("中").fontColor(Color.White).layoutWeight(1)
          Text("下").fontColor(Color.White)
        }
        .layoutWeight(1)

        // 右侧避让区域(根据实际需求设置)
        Column() {
          Text("右边的").fontColor(Color.White)
        }
        .expandSafeArea([SafeAreaType.CUTOUT], [SafeAreaEdge.END])
        .width('15%')
      }
      .width('100%') // 必须设置行容器宽度
    }
  }
  .backgroundColor(Color.Black)
  .hideTitleBar(true)
}

更多关于HarmonyOS 鸿蒙Next中横屏的状态下怎么避开安全区的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


可以参考一下这个帖子:横屏时如何规避刘海屏区域?

官方文档:安全区域

cke_471.png

【背景知识】

挖孔避让:横竖屏适配过程中,需要考虑核心内容与重要交互不要被挖孔区遮挡,如果被遮挡,则需进行局部内容避让;可滚动内容或非核心信息无需专门避让挖孔区;要避免因为避让挖孔导致左右侧留白不一致。

【解决方案】

方案一:设置组件安全区

组件安全区方案实现沉浸式是指通过设置组件的expandSafeArea属性,让内容覆盖系统栏区域,可以通过如下步骤,实现动态避让挖孔区。

  1. 在module.json5文件中声明metadata,配置避让挖孔区。
{
  "module" :
  {
    "name" : "entry",
    "type" : "entry",
    "metadata":
    [
      {
        "name": "avoid_cutout",
        "value": "true"
      }
    ],
    // ...
    "abilities" :
    [
      {
        "name" : "EntryAbility",
        "orientation": "landscape", // 设置横屏
        // ...
      }
    ]
  }
}
  1. 在页面根容器使用expandSafeArea属性,配置拓展安全区域SafeAreaType.CUTOUT,子组件不拓展挖孔区,即可在屏幕旋转时子组件自动避让挖孔区。
@Entry
@Component
struct Index {
  build() {
    Stack(){

      Image($r("app.media.test"))
        .objectFit(ImageFit.Contain)
        .align(Alignment.Center)
        .width('100%')
        .height('100%')
        .expandSafeArea([])

      Row(){
        Column(){
          Text("左边").fontColor(Color.White)
        }.backgroundColor(Color.Red)
        .width('10%')

        Column(){
          Text("上").fontColor(Color.White).backgroundColor(Color.Red)
          Text("中").fontColor(Color.White).backgroundColor(Color.Red).layoutWeight(1)
          Text("下").fontColor(Color.White).backgroundColor(Color.Red)
        }
        .layoutWeight(1)

        Column(){
          Text("右边").fontColor(Color.White)
        }.backgroundColor(Color.Red)
        .width('10%')
      }
      .width('100%')
      .height('100%')
      .expandSafeArea([])

    }.width('100%')
    .height('100%')
    .expandSafeArea()
  }
}

方案二:窗口全屏布局动态监听避让挖孔区

窗口全屏布局方案实现沉浸式是指通过setWindowLayoutFullScreen()实现全屏沉浸式。挖孔区域会随屏幕旋转而改变,需要使用on(‘avoidAreaChange’)动态监听挖孔区域变化,在监听回调中获取其挖孔区域信息,并根据挖孔区域信息动态刷新UI,保证在避让区变化后能够正确避让挖孔区。具体实现可以参考动态监听避让区变化

【总结】

避让挖孔区可以通过设置组件安全区或者窗口全屏布局动态监听避让挖孔区两种方案实现。

“metadata”:

[ { “name”: “avoid_cutout”, “value”: “true”, } ],

摄像头挖孔区域不属于避让区,页面默认不避让挖孔。

从API Version 12开始,可在module.json5中添加以下配置项, 摄像头挖孔区域会视为避让区,实现页面默认避让挖孔: 参考文档:https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-universal-attributes-expand-safe-area#expandsafearea

从API Version 10开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。

摄像头挖孔区域不属于避让区,页面默认不避让挖孔。

从API Version 12开始,可在module.json5中添加以下配置项, 摄像头挖孔区域会视为避让区,实现页面默认避让挖孔:

"metadata": [
    {
        "name": "avoid_cutout",
        "value": "true"
    }
]

参考文档地址: https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-universal-attributes-expand-safe-area

找到原因了, 其实是会自动避开安全区的,不需要写额外的代码,

只是,像我写的那样的代码, Row 里面左右两端的 Column 必须要设置宽度,才会避开安全区。

不设置宽度的话,它是默认全屏的。

previewableImage

在HarmonyOS Next中横屏避开安全区,可以使用WindowManagergetWindowAvoidArea方法获取安全区域信息。在Ability的onWindowStageCreate中通过windowStage.getWindow().getAvoidArea(type)获取具体区域(type包括TYPE_SYSTEMTYPE_CUTOUT等)。使用setWindowLayoutFullScreen(true)全屏后再通过setWindowLayout调整布局避开返回数据中的left/right/top/bottom值。安全区数据单位为像素,需结合实际屏幕分辨率处理。

在HarmonyOS Next中,可以通过expandSafeArea方法来避开挖孔屏的安全区域。从你的代码来看,已经使用了这个方法,但需要调整参数来确保在横屏模式下正确避开左侧挖孔。

建议修改左侧Column的expandSafeArea调用方式:

Column(){
  Text("左边的").fontColor(Color.White)
}
.backgroundColor(Color.Red)
.expandSafeArea([SafeAreaType.CUTOUT],[SafeAreaEdge.START])
.width('100%')

关键修改点:

  1. 只保留SafeAreaEdge.START参数,因为只需要处理左侧挖孔
  2. 添加width('100%')确保Column填满可用空间
  3. 移除了不必要的SafeAreaEdge.END参数

这样修改后,左侧红色区域会自动避开挖孔区域,同时保持右侧内容正常显示。

回到顶部