HarmonyOS鸿蒙Next中Tabs的TabContent高度问题
HarmonyOS鸿蒙Next中Tabs的TabContent高度问题 看图片,我的TabContent里面放的是一个List,我发现下面有部分区域没有展示出来,来回修改了height什么的都不行。请教各位有知道怎么回事的吗?
关键代码如下:
主类代码:
build() {
Column() {
CustomNavView({navTitle: "告警管理", navStack: this.warningPageStack, showBackBtn: false, showBottomLine: true})
Tabs({barPosition: BarPosition.Start, index: this.currentIndex, controller: this.controller}) {
TabContent() {
CurrentWarningListPage()
}
TabContent(){
WarningRecordListPage()
}
}
.vertical(false)
.barMode(BarMode.Fixed)
.barHeight(0)
.animationDuration(300)
.onChange((index: number) => {
this.currentIndex = index;
this.selectedIndex = index;
if(index === 0){
this.tabBgFlex = FlexAlign.Start;
} else {
this.tabBgFlex = FlexAlign.End;
}
})
.onAnimationStart((index: number, targetIndex: number, event: TabsAnimationEvent) => {
Logger.info(`----- currentOffset = ${event.currentOffset} ==== targetOffset = ${event.targetOffset}`);
Logger.info(`---------- index = ${index} --------- targetIndex = ${targetIndex}`);
if(index === targetIndex){
return;
}
this.selectedIndex = targetIndex;
if(targetIndex === 0){
this.tabBgFlex = FlexAlign.Start;
} else {
this.tabBgFlex = FlexAlign.End;
}
})
.width('100%')
.height('auto')
.backgroundColor(Color.Black)
}
.width('100%')
}
CurrentWarningListPage中代码如下
build() {
Refresh({refreshing: $$this.refreshing, builder: this.refreshHeader()}){
List(){
ForEach(this.dataArr, (item: number) => {
ListItem(){
WarningListCell()
}
})
ListItem(){
this.refreshFooter()
}
}
.onScrollIndex((start: number, end: number) => {
if(end >= this.dataArr.length - 1){
}
})
.scrollBar(BarState.Off)
.edgeEffect(EdgeEffect.Spring, {alwaysEnabled: true})
}
.width('100%')
.height('100%')
.onOffsetChange((offset: number) => {
this.refreshOffset = offset;
})
.onStateChange((state: RefreshStatus) => {
this.refreshState = state;
})
.onRefreshing(() => {
setTimeout(() => {
this.refreshing = false;
}, 5000)
})
}
可能是什么问题呢
更多关于HarmonyOS鸿蒙Next中Tabs的TabContent高度问题的实战教程也可以访问 https://www.itying.com/category-93-b0.html
开发者你好:
【背景知识】
- height:用于设置组件自身的高度,缺省时使用元素自身内容需要的高度。若子组件的高大于父组件的高,则会画出父组件的范围。
- margin:用于设置组件的外边距属性。
- layoutWeight:用于设置组件的布局权重,使组件在父容器(Row/Column/Flex)的主轴方向按照权重分配尺寸。父容器尺寸确定时,不设置layoutWeight属性或者layoutWeight属性生效值为0的元素优先占位,这些元素占位后在主轴留下的空间称为主轴剩余空间。设置了layoutWeight属性且layoutWeight属性生效值大于0的子元素会从主轴剩余空间中按照各自所设置的权重占比分配尺寸,分配时会忽略元素本身的尺寸设置。
- Flex组件:是以弹性方式布局子组件的容器组件,提供更加有效的方式对容器内的子元素进行排列、对齐和分配剩余空间。
【问题定位】
- 首先观察到List组件未设置高度,根据height属性说明:height缺省时使用元素自身内容需要的高度。所以List组件高度为子组件之和。
- 然后根据List的尺寸约束示例可以看到,当子组件主轴方向总尺寸超过List父组件尺寸时,List主轴方向尺寸适应List的父组件尺寸,所以List组件高度为屏幕高度。
- 再然后根据layoutWeight布局说明:不设置layoutWeight属性或者layoutWeight属性生效值为0的元素优先占位。所以List组件会在剩余空间内占位,导致List组件被下压,下压后List组件就有部分区域会超过当前屏幕高度,所以造成List展示不全现象。
- 最后可以利用ArkUI Inspector可以看到List组件超出屏幕范围。
【分析结论】
当List组件上面有其他元素并且List子组件高度之和超出屏幕范围时,会导致List组件被下压,造成List展示不全的问题。
【方案一】给List组件设置高度
设置固定高度以后List组件就会在限定的范围内滑动,比如设置300vp后List组件就在300vp内进行滑动:
List() {
// ...省略内容
}
.height(300)
注意:上文300vp只是演示效果,具体数值看业务需要;若height值超过剩余屏幕高度,比如1000vp,则设置无效
或者利用calc特性计算List组件在主轴方向剩余高度:
List() {
// 省略内容
}
.height('calc(100% - 200vp)')
注意:calc公式中200vp的高度为List上面Text组件的高度。
【方案二】给List组件设置layoutWeight属性
在主轴剩余空间内,设置了layoutWeight属性的子元素与兄弟元素会在主轴方向按照权重分配尺寸。给List组件设置layoutWeight属性即可:
List() {
// 省略内容
}
.layoutWeight(1)
注意:以上场景Text组件后面只有List组件,故layoutWeight设置无论何值都行,不过一般都会设置成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%')
}
【总结】
List组件由于其滚动特性一般不会设置其高度,而当List在父容器内有其他兄弟节点处于上方并且List组件高度超出屏幕范围时,就会造成List展示不全问题,本文提供四种方案进行解决,四种方案对比如下,开发者可以自行根据对比进行选择:
方案 | 原理 | 说明 |
---|---|---|
设置height | 约束List组件的高度 | 设置固定高度局限较多,应用场景较少;利用calc计算需要获悉上面节点的高度 |
设置layoutWeight | 在主轴剩余空间内分配List尺寸 | 应用场景最多,使用最方便,推荐使用 |
设置margin | 设置List组件的外边距 | 需要获悉上面节点的高度 |
使用Flex布局 | 利用弹性布局方式 | 会更改页面布局,需要根据实际情况选用 |
【常见FAQ】
Q:List组件被父容器组件包裹,父容器组件有同级组件时,单纯给List设置layoutWeight不生效该如何解决?
A:这是由于没有给List的父组件设置高度所致,给父容器也加上layoutWeight即可。
更多关于HarmonyOS鸿蒙Next中Tabs的TabContent高度问题的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
不过,经过尝试,给List组件设置layoutWeight
并没有作用。最终我是通过给父组件设置的padding解决的。和给List设置margin一个道理,
试下这种方式
@ComponentV2
struct cs002{
build() {
Tabs(){
TabContent(){
Column(){
//放置自定义组件.......
}
.height('100%')
.width('100%')
}
.height('100%')
.width('100%')
}
.height('100%')
.width('100%')
}
}
试了,不行。
是的,你看我代码,我注释了pandding, 加上padding的确可以正常展示,但我觉的这不是根本解决办法,或者没有理解问题的根源。所以想看看有没有其他的解决办法,
有要学HarmonyOS AI的同学吗,联系我:https://www.itying.com/goods-1206.html
试过的,不行,
在HarmonyOS Next中,Tabs组件的TabContent高度默认会填充剩余空间。若需自定义高度,可在TabContent布局属性中设置具体高度值,或用百分比布局。若内容超出,建议结合Scroll组件使用。可通过measureMode
属性控制测量模式,如设置为EXACTLY
来指定精确高度。注意父容器约束可能影响最终效果。