HarmonyOS 鸿蒙Next核心发现:expandSafeArea 仅在 Scroll 内容可滚动时才生效

HarmonyOS 鸿蒙Next核心发现:expandSafeArea 仅在 Scroll 内容可滚动时才生效 怎么才能确保 Scroll 内容全屏展示。包括状态栏

5 回复

尊敬的开发者,您好,
expandSafeArea并非在Scroll 内容可滚动时才生效。
滚动类容器内的组件不建议设置expandSafeArea属性,如果设置,需要按照组件嵌套关系,将当前节点到滚动类祖先容器间所有直接节点设置expandSafeArea属性,否则expandSafeArea属性在滚动后可能会失效,写法参考示例7
expandSafeArea使用事项可参考:expandSafeArea
如果还是不能解决您的问题,麻烦您提供下能复现问题的最小demo吧。

更多关于HarmonyOS 鸿蒙Next核心发现:expandSafeArea 仅在 Scroll 内容可滚动时才生效的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


expandSafeArea并不是依赖 Scroll 滚动时才生效,是不是其他因素影响了?

expandSafeArea

说明

  • 设置expandSafeArea属性进行组件绘制扩展时,建议组件尺寸不要设置固定宽高(百分比除外),当设置固定宽高(包括设置’auto’)时,扩展安全区域的方向只支持[SafeAreaEdge.TOP, SafeAreaEdge.START],扩展后的组件尺寸保持不变。
  • 安全区域不会限制内部组件的布局和大小,不会裁剪内部组件。
  • 当父容器为滚动容器时,组件设置expandSafeArea属性后,自身不会延伸,但仍可触发其子节点中设置了expandSafeArea的延伸范围更新。
  • 设置expandSafeArea()时,不传参,走默认值处理;设置expandSafeArea([],[])时,相当于入参是空数组,此时expandSafeArea属性设置无效。
  • 组件设置expandSafeArea生效的条件为:
    1. type为SafeAreaType.KEYBOARD时默认生效,表现为组件不避让键盘。
    2. 设置其他type,组件的边界与安全区域重合时组件能够延伸到安全区域下。例如:设备顶部状态栏高度100,那么组件在屏幕中的绝对位置需要为0 <= y <= 100。
  • 组件延伸到避让区时,在避让区的事件如点击事件等可能会被系统拦截,优先给状态栏等系统组件响应。
  • 滚动类容器内的组件不建议设置expandSafeArea属性,如果设置,需要按照组件嵌套关系,将当前节点到滚动类祖先容器间所有直接节点设置expandSafeArea属性,否则expandSafeArea属性在滚动后可能会失效,写法参考示例7
  • expandSafeArea属性仅作用于当前组件,不会向父组件或子组件传递,因此使用过程中,所有相关组件均需配置。
  • 同时设置expandSafeArea和position属性时,position属性会优先生效,expandSafeArea属性会后生效。对于未设置position、offset等绘制属性的组件,如果其边界未与避让区重叠,设置expandSafeArea属性将不生效,如弹窗和半模态组件。
  • 对于expandSafeArea属性无法生效的场景,若要将组件部署在避让区,需要手动调整组件的坐标。
// xxx.ets
import { ListDataSource } from './ListDataSource';

@Entry
@Component
struct ListExample {
  private arr: ListDataSource = new ListDataSource([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]);
  // private arr: ListDataSource = new ListDataSource([0, 1, 2, 3, 4, 5]);

  build() {
    Column() {
      List({ space: 20, initialIndex: 0 }) {
        LazyForEach(this.arr, (item: number) => {
          ListItem() {
            Text('' + item)
              .width('100%').height(100).fontSize(16)
              .textAlign(TextAlign.Center).borderRadius(10).backgroundColor(0xFFFFFF)
          }
        }, (item: number) => item.toString())
      }
      .listDirection(Axis.Vertical) // 排列方向
      .scrollBar(BarState.Off)
      .friction(0.6)
      .divider({ strokeWidth: 2, color: 0xFFFFFF, startMargin: 20, endMargin: 20 }) // 每行之间的分界线
      .edgeEffect(EdgeEffect.Spring) // 边缘效果设置为Spring
    }
    .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM])
    .backgroundColor(0xDCDCDC)
  }
}

提供下代码看下呢?

expandSafeArea

生效的前提:Scroll 内容总高度 > Scroll 视口高度(即内容可滚动) 2. 普通灯控件少,内容不足以溢出视口,所以需要额外 padding 撑高内容 3. 之前试过

  • statusBarHeight

(~54vp)→ 移了一半距离;

  • statusBarHeight * 2

(~108vp)→ 接近但还差一点 4. 说明实际缺口比 2 倍 statusBarHeight 略大,可能还受标题栏、底部安全区等因素影响 5. 选 200vp 是因为它足够大,能确保

任何屏幕尺寸

的设备内容都溢出,同时又不会大到让底部出现明显异常空白(因为 Scroll 本身有弹性边缘效果,多出的 padding 用户感知不到) 本质上是个 “确保可滚动” 的安全余量,不需要精确值,只要 > 实际缺口就行。

expandSafeArea在鸿蒙Next中用于扩展安全区域,仅当Scroll组件内容可滚动时生效。若内容未超出容器,该属性无效。

在HarmonyOS Next中,expandSafeArea 属性用于控制组件是否扩展到安全区域(如状态栏)之外。根据你的问题,要确保 Scroll 内容全屏展示(包括状态栏),需要注意以下几点:

  1. expandSafeArea 生效条件:该属性仅在 Scroll 内容可滚动时生效。如果内容高度不足,无法触发滚动,则扩展安全区域的效果可能不会显示。

  2. 确保内容可滚动

    • 确保 Scroll 组件内的内容高度超过 Scroll 容器的高度,以触发滚动行为。
    • 可以通过设置内容高度或添加足够多的子组件来实现。
  3. 全屏展示设置

    • 在 Scroll 组件上设置 expandSafeArea([safeAreaType.SYSTEM], { edge: safeAreaEdge.ALL }),以扩展到系统安全区域的所有边缘(包括顶部状态栏)。
    • 同时,确保 Scroll 的父容器或页面本身也支持全屏布局,例如使用 width('100%')height('100%')

示例代码结构:

Scroll() {
  // 确保内容足够长,可滚动
  Column() {
    // 多个子组件或设置固定高度
  }
  .width('100%')
  .height(2000) // 示例高度,确保可滚动
}
.width('100%')
.height('100%')
.expandSafeArea([safeAreaType.SYSTEM], { edge: safeAreaEdge.ALL })
  1. 检查布局约束:如果 Scroll 的父容器限制了高度(如固定值),可能影响全屏效果。建议使用百分比或 LayoutConstraint 适配。

  2. 预览与测试:在真机或模拟器上测试,因为安全区域的行为可能因设备而异。

通过以上步骤,可确保 Scroll 内容在可滚动时全屏展示,包括覆盖状态栏区域。

回到顶部