HarmonyOS5 便捷生活类——List展示不全(点主页有系列文章)

加入下方官方班级,得鸿蒙礼盒

一起拿鸿蒙礼盒,戳我戳我!!

本期活动时间:2025年8月1日-12月31日


问题现象

List组件与其他组件同级并且List子组件总尺寸超过List父组件尺寸时,会导致ListItem部分内容顶出父组件显示区域外,上滑至底部时其内容展示不全。

 
build() {
Column() {
Text('我是一级容器Column的Text组件')
.fontSize(18)
.width('100%')
.height(200)
.textAlign(TextAlign.Center)
.backgroundColor('#330a59f7')
List() {
ForEach([1, 2, 3, 4, 5, 6, 7], (item: number) => {
ListItem() {
Row() {
Text(item + '').fontSize(18)
}
.width('100%')
.height(200)
.justifyContent(FlexAlign.Center)
.backgroundColor($r('sys.color.container_modal_unfocus_background'))
.borderWidth(1)
.borderColor('#ff0a59f7')
}
})
}.scrollBar(BarState.Off)
}
.height('100%')
.width('100%')
}

问题效果如下:

效果预览

背景知识

  • height:用于设置组件自身的高度,缺省时使用元素自身内容需要的高度。若子组件的高大于父组件的高,则会画出父组件的范围。
  • margin:用于设置组件的外边距属性。
  • layoutWeight:用于设置组件的布局权重,使组件在父容器(Row/Column/Flex)的主轴方向按照权重分配尺寸。父容器尺寸确定时,不设置layoutWeight属性或者layoutWeight属性生效值为0的元素优先占位,这些元素占位后在主轴留下的空间称为主轴剩余空间。设置了layoutWeight属性且layoutWeight属性生效值大于0的子元素会从主轴剩余空间中按照各自所设置的权重占比分配尺寸,分配时会忽略元素本身的尺寸设置。
  • Flex组件:是以弹性方式布局子组件的容器组件,提供更加有效的方式对容器内的子元素进行排列、对齐和分配剩余空间。

问题定位

  1. 首先观察到List组件未设置高度,根据height属性说明:height缺省时使用元素自身内容需要的高度。所以List组件高度为子组件之和200vp*7。
  2. 然后根据List的尺寸约束示例可以看到,当子组件主轴方向总尺寸超过List父组件尺寸时,List主轴方向尺寸适应List的父组件尺寸,而200vp*7 > 父组件高度100%,所以List组件高度为屏幕高度,示意图如下:

  3. 再然后根据layoutWeight布局说明:不设置layoutWeight属性或者layoutWeight属性生效值为0的元素优先占位。所以List组件会在剩余空间内占位,导致List组件被下压,下压后List组件就有部分区域会超过当前屏幕高度,所以造成List展示不全现象。
  4. 最后可以利用ArkUI Inspector可以看到List组件超出屏幕范围,超出的距离刚好是上面Text组件占据高度200vp。

分析结论

当List组件上面有其他元素并且List子组件高度之和超出屏幕范围时,会导致List组件被下压,造成List展示不全的问题。

修改建议

  • 方案一:给List组件设置高度。

    设置固定高度以后List组件就会在限定的范围内滑动,比如设置300vp后List组件就在300vp内进行滑动。

     

    说明

    上文300vp只是演示效果,具体数值看业务需要;若height值超过剩余屏幕高度,比如1000vp,则设置无效。

    或者利用calc特性计算List组件在主轴方向剩余高度。

     

    说明

    calc公式中200vp的高度为List上面Text组件的高度。

  • List() {
    // ...
    }
    .height('calc(100% - 200vp)')

  • List() {
    // ...
    }
    .height(300)

  • 方案二:给List组件设置layoutWeight属性。

    在主轴剩余空间内,设置了layoutWeight属性的子元素与兄弟元素会在主轴方向按照权重分配尺寸。给List组件设置layoutWeight属性即可。

     

    说明

    以上场景Text组件后面只有List组件,故layoutWeight设置无论何值都行,不过一般都会设置成layoutWeight(1)。

  • List() {
    // ...
    }
    .layoutWeight(1)

  • 方案三:给List组件设置margin属性。

    利用ArkUI Inspector可以看到List组件超出屏幕范围,超出的距离刚好是上面Text组件占据高度200vp。而margin属性就是用于设置组件的外边距,所以给List组件设置margin底部200vp即可。

     
    List() {
    // ...
    }
    .margin({ bottom: 200 })

  • 方案四:使用Flex布局。

    Flex组件提供更加有效的方式对容器中的子元素进行排列、对齐和分配剩余空间,设置FlexWrap.NoWrap即可让子元素尽可能约束在容器内。

     
    build() {
    Flex({ wrap: FlexWrap.NoWrap, alignItems: ItemAlign.Center, direction: FlexDirection.Column }) {
    Text('我是一级容器Column的Text组件')
    
    List() {
    // ...
    }
    }
    .height('100%')
    .width('100%')
    }

常见FAQ

Q:List组件被父容器组件包裹,父容器组件有同级组件时,单纯给List设置layoutWeight不生效该如何解决?

A:这是由于没有给List的父组件设置高度所致,给父容器也加上layoutWeight即可。

总结

List组件由于其滚动特性一般不会设置其高度,而当List在父容器内有其他兄弟节点处于上方并且List组件高度超出屏幕范围时,就会造成List展示不全问题,本文提供四种方案进行解决,四种方案对比如下,开发者可以自行根据对比进行选择。

方案

原理

场景说明

设置height

约束List组件的高度。

  1. 固定高度会限制List只能在有限范围内展示,根据实际业务需要。
  2. 利用calc计算设置动态高度等同于layoutWeight效果,但需要获悉上面节点的高度使用较为麻烦。

设置layoutWeight

在主轴剩余空间内分配List尺寸。

  1. 应用场景最多,使用最方便,推荐使用。

设置margin

设置List组件的外边距。

  1. 需要获悉上面节点的高度,有其他方向margin设置需求时可以搭配使用。
  2. 若下方还有节点则会设置失败,局限性较大。

使用Flex布局

利用弹性布局特性。

  1. FlexWrap.NoWrap不换行时List默认能展示完全。
  2. FlexWrap.Wrap换行时必须搭配height属性使用,否则List内容会向右溢出。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值