HarmonyOS鸿蒙Next Grid网格布局如何实现瀑布流效果?网格布局开发指南
HarmonyOS鸿蒙Next Grid网格布局如何实现瀑布流效果?网格布局开发指南 armonyOS 5.0,DevEco Studio 5.0
- 需要实现图片瀑布流展示效果
- 不清楚Grid组件的配置方法
- 希望了解不等高网格的实现方式
希望了解HarmonyOS Grid组件的使用方法,实现瀑布流和网格布局
1. 基础网格布局
@Entry
@Component
struct GridPage {
@State items: number[] = Array.from({ length: 20 }, (_, i) => i + 1)
build() {
Grid() {
ForEach(this.items, (item: number) => {
GridItem() {
Column() {
Text(`${item}`)
.fontSize(16)
.fontColor($r('app.color.text_primary'))
}
.width('100%')
.height(100)
.backgroundColor($r('app.color.surface'))
.borderRadius(12)
.justifyContent(FlexAlign.Center)
}
}, (item: number) => item.toString())
}
.columnsTemplate('1fr 1fr') // 两列等宽
.columnsGap(12)
.rowsGap(12)
.padding(16)
.backgroundColor($r('app.color.background'))
}
}
2. 瀑布流布局(WaterFlow)
@Observed
class WaterFlowItem {
id: string
height: number
color: string
constructor(id: string, height: number, color: string) {
this.id = id
this.height = height
this.color = color
}
}
@Entry
@Component
struct WaterFlowPage {
@State items: WaterFlowItem[] = []
aboutToAppear(): void {
const colors = ['#36e27b', '#3b82f6', '#f97316', '#a855f7', '#ef4444']
this.items = Array.from({ length: 30 }, (_, i) => {
return new WaterFlowItem(
i.toString(),
100 + Math.random() * 150, // 随机高度
colors[i % colors.length]
)
})
}
build() {
WaterFlow() {
ForEach(this.items, (item: WaterFlowItem) => {
FlowItem() {
Column() {
Text(item.id)
.fontSize(20)
.fontWeight(FontWeight.Bold)
.fontColor(Color.White)
}
.width('100%')
.height(item.height)
.backgroundColor(item.color)
.borderRadius(12)
.justifyContent(FlexAlign.Center)
}
}, (item: WaterFlowItem) => item.id)
}
.columnsTemplate('1fr 1fr')
.columnsGap(12)
.rowsGap(12)
.padding(16)
.backgroundColor($r('app.color.background'))
}
}
3. 图片瀑布流
interface ImageItem {
id: string
url: string
aspectRatio: number
}
@Entry
@Component
struct ImageWaterFlowPage {
@State images: ImageItem[] = []
aboutToAppear(): void {
// 模拟图片数据
this.images = [
{ id: '1', url: 'https://example.com/1.jpg', aspectRatio: 1.5 },
{ id: '2', url: 'https://example.com/2.jpg', aspectRatio: 0.8 },
// ...
]
}
build() {
WaterFlow() {
ForEach(this.images, (item: ImageItem) => {
FlowItem() {
Image(item.url)
.width('100%')
.aspectRatio(item.aspectRatio)
.objectFit(ImageFit.Cover)
.borderRadius(12)
}
}, (item: ImageItem) => item.id)
}
.columnsTemplate('1fr 1fr')
.columnsGap(8)
.rowsGap(8)
.padding(16)
}
}
4. Grid常用配置
Grid()
.columnsTemplate('1fr 1fr 1fr') // 三列等宽
.rowsTemplate('1fr 1fr') // 两行等高
.columnsGap(12) // 列间距
.rowsGap(12) // 行间距
.scrollBar(BarState.Off) // 隐藏滚动条
.cachedCount(4) // 缓存数量
5. 跨行跨列
GridItem() {
// 内容
}
.columnStart(0) // 起始列
.columnEnd(1) // 结束列(跨2列)
.rowStart(0) // 起始行
.rowEnd(0) // 结束行
更多关于HarmonyOS鸿蒙Next Grid网格布局如何实现瀑布流效果?网格布局开发指南的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
鸿蒙Next的Grid组件可通过自定义布局管理器实现瀑布流。在GridItemContainer中重写onMeasure和onLayout方法,动态计算每个网格项的位置和大小。使用GridItemProvider管理数据源,结合GridItem的宽高自适应。通过设置不同的列宽和行高参数,实现错落排列的瀑布流视觉效果。
在HarmonyOS Next中,使用Grid组件实现瀑布流效果,核心在于结合其列数配置与子项的自适应高度。Grid本身是等宽布局,瀑布流的“不等高”需要子组件内容撑开高度来实现。
以下是关键步骤和代码示例:
-
Grid组件基础配置: 设置
columnsTemplate为固定列数(如'1fr 1fr'代表两列),rowsTemplate为'auto',让行高自适应内容。同时启用layoutDirection为GridDirection.Row(默认值,按行优先排列)。Grid() { // ... 子项内容 } .columnsTemplate('1fr 1fr') // 定义列数,例如2列 .rowsTemplate('auto') // 行高自适应内容 .layoutDirection(GridDirection.Row) .width('100%') -
子项内容与高度自适应: 瀑布流效果依赖于每个网格子项内容(尤其是图片)具有不同的高度。将图片或内容组件放入
GridItem()中,不设置固定高度,依靠内容自身高度或aspectRatio(宽高比)属性来撑开GridItem,从而实现错落布局。ForEach(this.imageData, (item: ImageData) => { GridItem() { Column() { Image(item.src) .aspectRatio(item.ratio) // 关键:通过宽高比控制图片显示高度 .width('100%') .objectFit(ImageFit.Cover) Text(item.title) // ... 文本样式 } .width('100%') // 注意:Column不设置固定高度,由内部Image和Text撑开 } }) -
数据模型: 数据源中应包含计算或预设的宽高比(
ratio),这是实现高度差异的关键。class ImageData { src: ResourceStr; ratio: number; // 宽高比,用于.aspectRatio() title: string; }
重要说明:
- 瀑布流实现原理:Grid按行优先顺序排列,每行的单元格等高。但由于设置了
rowsTemplate('auto')且每个GridItem内容高度不同,Grid会自动将内容分配至最短的列,从而实现视觉上的错落瀑布流效果。这要求子项高度是动态的。 - 性能考虑:对于大量图片,建议使用
LazyForEach进行列表渲染优化,并配合图片缓存策略。 - 网格布局(等高等宽)只需为子项设置固定尺寸或比例即可。
这种方法直接利用Grid的流式布局能力,无需复杂计算即可实现基础的瀑布流展示。

