HarmonyOS鸿蒙Next中Grid组件滑动到最下面为什么会超出父容器

HarmonyOS鸿蒙Next中Grid组件滑动到最下面为什么会超出父容器

Grid组件 滑动到最下面为什么会超出父容器

8 回复

开发者你好,控制子组件不超过父组件的范围可以给父组件设备clip属性或者控制子组件的高度,若是都不满足您的需求,还请提供下您这边的可以复现问题的demo以便分析。

【背景知识】

【解决方案】 给父组件设置裁剪属性clip,并设置值为true,该属性可用于设置是否对子组件超出当前组件范围外的区域进行裁剪。可参考官网链接:clip。子组件的实际显示可以超出父组件范围的原因是:图层是叠加显示的,子视图宽高均可超过父视图,一些操作系统平台默认设置剪裁,Harmony OS平台设置默认不剪裁。

Grid组件高度自适应:

当Grid组件不设置height、width属性或者设置为auto时,会自适应GridItem的总高度和总宽度。

  1. 可通过maxcount属性、minCount属性设置最大最小行列数。
  2. 通过cellLength属性设置行列的宽高。

提示:

  1. maxcount属性、minCount属性、cellLength属性的行列控制变换由layoutDirection属性决定。
  2. 当Grid组件的rowsTemplate属性、columnsTemplate属性都不设置时,layoutDirection属性、cellLength属性、maxcount属性、minCount属性才可生效。

示例代码如下:

@Entry
@Component
struct GridExample {
  @State numbers: string[] = []
  @State rowMaxCount: number = 5
  @State cellHeight: number = 50
  @State itemNumber: number = 30

  aboutToAppear() {
    for (let i = 1; i <= 30; i++) {
      this.numbers.push(i.toString())
    }
  }

  build() {
    Scroll() {
      Column({ space: 5 }) {
        Text('修改一行最大显示个数+1')
          .fontSize(15)
          .onClick(() => {
            // 当单行最大的个数超出屏幕宽度时,即使最大个数增加也不会改变布局
            this.rowMaxCount += 1
          })
        Text('修改一行最大显示个数-1')
          .fontSize(15)
          .onClick(() => {
            // 避免单行最大个数小于最小个数,该示例一行最小设置两个GridItem
            if (this.rowMaxCount > 2) {
              this.rowMaxCount -= 1
            }
          })
        Text('修改一行行高-10')
          .fontSize(15)
          .onClick(() => {
            this.cellHeight -= 10
          })
        Text('修改一行行高+10')
          .fontSize(15)
          .onClick(() => {
            this.cellHeight += 10
          })
        Text('增加Item个数')
          .fontSize(15)
          .onClick(() => {
            this.itemNumber += 1
            this.numbers.push(this.itemNumber.toString())
          })
        Grid() {
          ForEach(this.numbers, (day: string) => {
            GridItem() {
              Text(day)
                .fontSize(16)
            }
            .width(40)
            .height(40)
            .borderWidth(2)
            .borderColor(Color.Black)
          }, (day: string) => day)
        }
        .columnsGap(5)
        .rowsGap(5)
        .backgroundColor(0xAFEEEE)
        .maxCount(this.rowMaxCount) // GridDirection.Row的模式下,该属性表示一行最多放置的个数
        .minCount(2) // GridDirection.Row的模式下,该属性表示一行最少放置的个数,本示例为两个
        .cellLength(this.cellHeight) // GridDirection.Row的模式下,该属性行高
        .layoutDirection(GridDirection.Row) // 横向布局,先一行占满后再排下一行
      }
      .width('100%')
      .margin({ top: 5 })
      .align(Alignment.Center)
    }
  }
}

更多关于HarmonyOS鸿蒙Next中Grid组件滑动到最下面为什么会超出父容器的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


背景知识:

  • Grid未设置固定高度

    当Grid未显式设置height属性时,默认会继承父组件高度1。若父容器高度不足且Grid内容超出,会导致滚动时子项溢出父容器边界。

  • 布局计算逻辑冲突

    Grid的行列模板(如rowsTemplate或columnsTemplate)未正确适配父容器尺寸,或子项尺寸未被动态计算,导致内容溢出。

  • 滚动容器嵌套问题

    Grid自身不具备滚动能力,若将其嵌套在Scroll等滚动容器中且未正确控制布局层级,可能引发尺寸计算异常。

问题解决:

1. 显式设置Grid高度

通过动态计算Grid高度确保其适配父容器。例如根据子项数量计算总高度:

@Entry
@Component
struct Example {
  data: string[] = ['Item1', 'Item2', 'Item3', 'Item4', 'Item5'];
  
  // 计算Grid总高度:假设每行高度100vp,总行数向上取整
  getGridHeight() {
    const rows = Math.ceil(this.data.length / 2); // 每行2列
    return rows * 100;
  }

  build() {
    Column() {
      Grid() {
        ForEach(this.data, (item: string) => {
          GridItem() {
            Text(item).height(100).width('100%')
          }
        })
      }
      .columnsTemplate('1fr 1fr') // 每行两列均分宽度
      .height(this.getGridHeight()) // 动态设置高度
    }
  }
}

2. 使用List替代Grid实现自适应

若Grid无法满足需求,可改用List组件并设置lanes属性实现分列布局,自动撑高父容器:

List({ space: 10 }) {
  ForEach(this.data, (item: string) => {
    ListItem() {
      Text(item).height(100).width('100%')
    }
  })
}
.lanes(2) // 两列布局
.alignListItem(ListItemAlign.Center)

3. 控制父容器约束

确保父容器高度足够且无溢出限制。例如通过Scroll包裹Grid并设置高度约束:

Scroll() {
  Grid() {
    // 子项内容
  }
  .columnsTemplate('1fr 1fr')
}
.height('100%') // 父容器高度占满可用空间

为Grid的父容器(如Scroll)设置固定高度或有效百分比高度:

struct Example {
  build() {
    Scroll() {
      Grid() { /* Grid内容 */ }
        .columnsTemplate('1fr 1fr')
        .height('100%') // Grid高度占满父容器
    }
    .height('80%') // Scroll父容器高度明确设置
  }
}

参考地址

https://developer.huawei.com/consumer/cn/doc/harmonyos-faqs/faqs-arkui-241

找HarmonyOS工作还需要会Flutter的哦,有需要Flutter教程的可以学学大地老师的教程,很不错,B站免费学的哦:https://www.bilibili.com/video/BV1S4411E7LY/?p=17,

高度问题,可以检查一下,每个view的高度

可以发一下截图看一下;

在HarmonyOS鸿蒙Next中,Grid组件滑动超出父容器边界,通常是因为Grid默认支持弹性滚动,未限制滚动范围。可通过设置布局属性控制:在Grid的父容器设置clip属性为true来裁剪溢出内容,或在Grid组件上设置scrollable属性为false禁用滚动。

在HarmonyOS Next中,Grid组件滑动到底部时内容超出父容器,通常是由于布局约束或样式设置问题导致的。以下是常见原因及解决方案:

  1. 父容器高度未限制
    Grid的父容器(如ColumnStack)若未设置固定高度或百分比高度,可能导致Grid无限扩展。建议为父容器设置明确的高度约束,例如:

    Column() {
      Grid() { ... }
    }
    .height('100%')  // 或固定值,如'80%'、500等
    
  2. Grid未启用滚动或滚动配置异常
    Grid需明确设置scrollBar属性或通过scroll方法启用滚动,并确保滚动方向正确。示例:

    Grid() { ... }
    .scrollBar(BarState.On)  // 启用滚动条
    .layoutWeight(1)         // 在弹性布局中占满剩余空间
    
  3. 内容高度计算偏差
    Grid的columnsTemplaterowsTemplate若使用自适应单位(如1fr),结合动态内容可能导致总高度超出预期。可尝试:

    • 检查模板定义是否合理,避免行/列数过多。
    • 使用maxHeight限制Grid最大高度。
  4. 嵌套滚动冲突
    若父容器也是可滚动组件(如Scroll),可能与Grid滚动产生冲突。建议:

    • 仅保留一个滚动容器,或将Grid的scrollBar设为BarState.Off,由父容器统一处理滚动。
  5. 样式覆盖问题
    自定义样式中的marginpaddingposition可能导致布局溢出。检查并调整相关样式属性。

示例修正代码

Column() {
  Grid() {
    // Grid内容
  }
  .columnsTemplate('1fr 1fr')
  .rowsTemplate('1fr 1fr')
  .scrollBar(BarState.On)
}
.height('100%')  // 限制父容器高度
.width('100%')

通过约束父容器高度、合理配置Grid滚动属性,可解决滑动到底部溢出的问题。若仍存在异常,建议检查布局层次和样式优先级。

回到顶部