加入下方官方班级,得鸿蒙礼盒
本期活动时间: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组件:是以弹性方式布局子组件的容器组件,提供更加有效的方式对容器内的子元素进行排列、对齐和分配剩余空间。
问题定位
- 首先观察到List组件未设置高度,根据height属性说明:height缺省时使用元素自身内容需要的高度。所以List组件高度为子组件之和200vp*7。
- 然后根据List的尺寸约束示例可以看到,当子组件主轴方向总尺寸超过List父组件尺寸时,List主轴方向尺寸适应List的父组件尺寸,而200vp*7 > 父组件高度100%,所以List组件高度为屏幕高度,示意图如下:

- 再然后根据layoutWeight布局说明:不设置layoutWeight属性或者layoutWeight属性生效值为0的元素优先占位。所以List组件会在剩余空间内占位,导致List组件被下压,下压后List组件就有部分区域会超过当前屏幕高度,所以造成List展示不全现象。
- 最后可以利用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组件的高度。 |
|
| 设置layoutWeight | 在主轴剩余空间内分配List尺寸。 |
|
| 设置margin | 设置List组件的外边距。 |
|
| 使用Flex布局 | 利用弹性布局特性。 |
|
1088

被折叠的 条评论
为什么被折叠?



