
鸿蒙原生 ArkTS 布局实战Grid WaterFlow 混合布局顶部网格 底部瀑布流一、引言在移动端应用开发中混合布局是首页设计的常见模式。典型的「顶部网格分类 底部瀑布流内容推荐」布局既能高效展示多入口Grid又能以错落有致的卡片流WaterFlow承载大量内容兼顾信息密度与视觉层次。HarmonyOS NEXT 的 ArkUI 声明式框架提供了Grid和WaterFlow两个高性能布局容器配合Column纵向容器可以非常优雅地实现这一经典布局。本文从零开始构建一个完整的示例应用深入剖析每个组件的配置要点及混合布局的实现细节。二、项目环境项目版本操作系统HarmonyOS NEXTAPI 版本24对应 SDK 7.0.0开发工具DevEco Studio NEXT构建系统hvigor 6.23语言ArkTS声明式 UI 装饰器语法在build-profile.json5中确认 SDK 配置{ app: { products: [ { name: default, targetSdkVersion: 7.0.0(24), compatibleSdkVersion: 7.0.0(24), runtimeOS: HarmonyOS } ] } }三、整体布局架构我们使用三层嵌套实现完整的混合布局Column根容器撑满全屏 ├── Column顶部网格区域 │ ├── Row ← 热门分类 标题栏 │ └── Grid ← 2×2 固定网格不滚动 │ ├── GridItem → 新品推荐圆角卡片 │ ├── GridItem → 热门榜单 │ ├── GridItem → 限时特惠 │ └── GridItem → 每日签到 │ └── Column底部瀑布流区域layoutWeight 占满剩余空间 ├── Row ← ✨ 为你推荐 标题栏 └── WaterFlow ← 2 列瀑布流自管理滚动 ├── FlowItem → 卡片 1200vp ├── FlowItem → 卡片 2280vp ├── FlowItem → 卡片 3160vp └── ... → 共 12 项高度 160~310vp 不等关键设计原则Grid固定高度不参与页面滚动——作为「顶部导航」区域始终可见或随页面整体滚动WaterFlowlayoutWeight(1)填满剩余空间完全接管其内容区域的纵向滚动Column作为串联容器将两个布局区域纵向排列四、数据模型层Observed 装饰器ArkTS 中使用Observed装饰类使其属性变化可被 UI 观察。这是State数组深度观测的前提。ObservedclassGridCategory{name:string;icon:string;color:number;constructor(name:string,icon:string,color:number){this.namename;this.iconicon;this.colorcolor;}}ObservedclassWaterfallItem{title:string;description:string;height:number;// 卡片高度单位 vp —— 控制瀑布流错落效果color:number;// 卡片色调constructor(title:string,description:string,height:number,color:number){this.titletitle;this.descriptiondescription;this.heightheight;this.colorcolor;}}为什么用Observed在 ArkTS 中State装饰的数组只观测引用变化如push、splice、重新赋值。当数组中对象的属性发生变化时需要Observed装饰该类才能触发 UI 刷新。虽然本示例不涉及动态属性修改但这是生产环境最佳实践。五、顶部 Grid 网格布局详解5.1 布局配置Grid(){ForEach(this.gridList,(item:GridCategory){GridItem(){this.GridCell(item);}},(item:GridCategory,index?:number)index!.toString());}.columnsTemplate(1fr 1fr)// 2 列等宽.rowsTemplate(1fr 1fr)// 2 行等高.columnsGap(12)// 列间距 12vp.rowsGap(12)// 行间距 12vp.height(180)// 固定高度不滚动.clip(true)// 超限裁剪.padding({left:16,right:16});5.2 关键属性解析属性值说明columnsTemplate1fr 1fr两列等宽fr是网格的弹性单位1fr表示等分剩余空间rowsTemplate1fr 1fr两行等高columnsGap12列与列之间 12vp 间距rowsGap12行与行之间 12vp 间距height180固定高度——与rowsTemplate配合确保 Grid 不自带滚动cliptrue超出高度部分裁剪避免与下方 WaterFlow 重叠5.3 「固定高度不滚动」的意义Grid组件默认拥有自己的滚动行为——当内容超出设定高度时会内部滚动。但在混合布局中我们不希望 Grid 独立滚动而是让整体由 WaterFlow 统一管理滚动。因此设置height(180)clip(true)将 Grid 限制为 2×2 静态网格。5.4 Grid 单元格Builder 子组件BuilderGridCell(item:GridCategory){Column(){// 圆形图标背景Text(item.icon).fontSize(32).width(48).height(48).backgroundColor(Color.White).borderRadius(24);// 分类名称Text(item.name).fontSize(14).fontWeight(FontWeight.Medium).fontColor(#333333).margin({top:8});}.width(100%).height(100%).justifyContent(FlexAlign.Center).alignItems(HorizontalAlign.Center).backgroundColor(item.color).borderRadius(14).shadow({radius:6,offsetX:0,offsetY:3,color:0x22000000});}设计要点Builder将 UI 抽取为独立子组件避免build()方法膨胀白色圆形背景托起 emoji 图标形成「图标在卡片中央」的视觉效果半透明阴影0x22为 alpha 通道对应约 13% 不透明度增加层次感.width(100%).height(100%)使单元格撑满GridItem的区域六、底部 WaterFlow 瀑布流布局详解6.1 布局配置WaterFlow(){ForEach(this.waterfallList,(item:WaterfallItem){FlowItem(){this.WaterfallCell(item);}},(item:WaterfallItem,index?:number)index!.toString());}.columnsTemplate(1fr 1fr)// 2 列等宽.columnsGap(10)// 列间距 10vp.rowsGap(10)// 行间距 10vp.layoutWeight(1)// 填满 Column 剩余空间.width(100%).padding({left:12,right:12}).backgroundColor(#F5F5F5).onReachEnd((){// 触底加载更多console.info([WaterFlow] 触底可在此加载更多数据);}).onReachStart((){// 到顶console.info([WaterFlow] 到达顶部);}).onScrollIndex((firstIndex:number,lastIndex:number){console.info([WaterFlow] 可见区间: [${firstIndex},${lastIndex}]);});6.2 核心属性解析属性值说明columnsTemplate1fr 1fr两列等宽和 Grid 语法一致columnsGap10列间距rowsGap10行间距WaterFlow 中表现为垂直间距layoutWeight1在 Column / Row / Flex 中占据剩余比例空间onReachEnd回调上拉加载更多的入口适合数据分页onReachStart回调下拉刷新判断点onScrollIndex回调获取当前可见区间可用于埋点或懒加载6.3 WaterFlow 的工作原理WaterFlow 是 ArkUI 提供的高性能瀑布流容器其核心机制自动布局按columnsTemplate分列每个FlowItem从上到下依次排入当前最短列按需渲染只渲染可见区域的FlowItem内存与性能优于手动计算位置自管理滚动无需外层Scroll包裹自身处理手势滚动高度自适应每个FlowItem的高度独立计算形成错落有致的「瀑布」效果6.4 瀑布流卡片Builder 子组件BuilderWaterfallCell(item:WaterfallItem){Column(){// 模拟图片区域Column().width(100%).height(item.height-80)// 根据 item.height 动态计算图片区.borderRadius({topLeft:12,topRight:12}).backgroundColor(item.color);// 文字内容区域Column(){Text(item.title).fontSize(15).fontWeight(FontWeight.Bold).maxLines(1).textOverflow({overflow:TextOverflow.Ellipsis});Text(item.description).fontSize(12).lineHeight(18).maxLines(2).textOverflow({overflow:TextOverflow.Ellipsis}).margin({top:4});}.padding({left:10,right:10,top:8,bottom:10}).width(100%).layoutWeight(1);}.width(100%).height(item.height)// 每个卡片独立高度.backgroundColor(Color.White).borderRadius(12).shadow({radius:4,offsetX:0,offsetY:2,color:0x15000000});}错落感来源12 张卡片的高度从 160vp 到 310vp 不等WaterFlow 自动将每个卡片排入当前最短的列产生自然的「瀑布」错落效果。数据示例 晨曦山峦 200vp │ 城市夜景 280vp 海洋日记 160vp │ 林间小径 240vp 星空物语 300vp │ 咖啡时光 180vp 花海漫游 260vp │ 古建筑韵 220vp 美食探索 190vp │ 极光之舞 310vp 沙漠驼铃 170vp │ 湖畔垂钓 250vp七、混合布局的尺寸管理7.1 layoutWeight 的妙用本示例中最关键的尺寸管理手段是layoutWeightColumn(){// ... 顶部 Grid 区域自然高度}// ...没有 layoutWeight取自身高度Column(){// ... 标题WaterFlow().layoutWeight(1)// WaterFlow 填满此 Column}.layoutWeight(1)// 此 Column 填满根 Column 的剩余空间工作流程根Column高度为100%全屏顶部 Grid 区域按内容自然高度渲染约 240vp底部 WaterFlow 区域的Column设置了.layoutWeight(1)自动占据剩余全部空间该 Column 内部的WaterFlow同样设置了.layoutWeight(1)填满 Column 内剩余高度WaterFlow 在自己的有效区域内管理滚动超出的卡片内容通过内部滚动查看7.2 为什么用两层 Column有人可能会问为什么不在根 Column 直接放 WaterFlow// ❌ 不推荐的简化写法Column(){Grid()// 顶部网格.height(180);// 固定高度WaterFlow()// 瀑布流.layoutWeight(1);// 填满剩余空间}这种写法理论上可行但实际使用中存在两个问题标题缺失Grid 和 WaterFlow 各自需要标题栏“热门分类”、“为你推荐”需要额外的布局容器样式隔离顶部 Grid 区域有白色背景 圆角底部 WaterFlow 区域有灰色背景用两层 Column 可以天然隔离样式作用域因此两层 Column 的结构在可维护性和视觉还原度上更优。八、API 24 新增特性与最佳实践HarmonyOS NEXT API 24SDK 7.0.0在布局方面带来以下改进8.1 性能优化WaterFlow 的懒加载性能提升配合LazyForEach实现真正按需渲染千级数据量也不卡顿Grid 的复用机制GridItem支持节点复用减少频繁建销毁的开销8.2 推荐使用 ObservedV2 Trace虽然本示例使用Observed它在 API 24 中仍然兼容但 API 24 推荐使用新的装饰器体系ObservedV2classWaterfallItem{Tracetitle:string;Tracedescription:string;Traceheight:number0;Tracecolor:number0;}ObservedV2Trace的粒度更细仅标记需要观测的属性性能开销更低。8.3 WaterFlow onReachEnd 的分页实践在实际项目中onReachEnd可以配合分页加载Statepage:number1;StateisLoading:booleanfalse;WaterFlow(){// ...}.onReachEnd((){if(this.isLoading)return;this.isLoadingtrue;this.page;loadMoreData(this.page).then((newItems){this.waterfallList.push(...newItems);this.isLoadingfalse;});});九、运行效果在 DevEco Studio 中连接模拟器或真机运行后可以看到顶部4 个彩色圆角卡片排成 2×2 网格每个卡片中央显示图标与分类名称底部有柔和阴影底部双列瀑布流卡片依次排布卡片高度从 160vp 到 310vp 不等左列和右列的卡片起始位置不同形成自然的「瀑布」落差视觉效果滚动交互上滑时 WaterFlow 区域流畅滚动下滑到顶触发onReachStart回调滑到底触发onReachEnd回调视觉层次网格区白色背景 大圆角瀑布流区浅灰背景两者之间通过margin隔离层次分明十、总结本文通过一个完整的示例详细讲解了如何在 HarmonyOS NEXT 中使用Grid WaterFlow Column实现「顶部网格 底部瀑布流」的混合布局。核心收获知识点要点Grid 固定高度配合.clip(true)关闭内部滚动作为静态网格区域WaterFlow 自管理滚动layoutWeight(1)填满剩余空间内部滚动不冲突Column 串联两个 Column 分别承载 Grid 和 WaterFlow样式隔离Builder 抽离子组件提升代码可读性与复用性Observed 数据模型支持深度属性变化的 UI 观测onReachEnd 分页回调真正的上拉加载更多入口这套布局模式适用于绝大多数移动端首页——淘宝、京东、小红书等主流应用均采用类似结构。掌握了 Grid WaterFlow 混合布局就掌握了鸿蒙原生开发中最常用的首页架构。十一、参考资料HarmonyOS NEXT 开发文档 - ArkUI 布局WaterFlow 组件 APIGrid 组件 APIObserved 和 ObservedV2 装饰器