OpenHarmony 网格、列表进阶与懒加载实战开发

发布时间:2026/7/25 3:11:38
OpenHarmony 网格、列表进阶与懒加载实战开发 承接前两篇 ArkUI 组件内容本文聚焦Grid 网格布局、List 列表高阶用法、组件懒加载、瀑布流等高频实用能力结合完整案例讲解特性、适配方案与性能优化适合页面布局进阶开发。一、概述在应用开发中图文宫格、商品陈列、相册、分类菜单等场景传统 Row/Column 布局已无法满足需求。Grid网格组件专门实现多列排布而List除基础列表外还支持分组、下拉刷新、上拉加载配合懒加载可以大幅优化长列表、多图页面的内存占用与渲染速度是大型应用必备技术。二、Grid 网格布局组件Grid 用于实现行列规则排列的宫格布局广泛应用于功能菜单、相册、商品列表、图标导航。搭配GridItem作为列表项使用。2.1 基础网格固定列数核心参数columnsTemplate定义列数与列宽rowsTemplate定义行数columnGap/rowGap设置行列间距。Entry Component struct GridBasicDemo { // 模拟宫格数据 gridData: string[] [首页, 分类, 购物车, 我的, 消息, 设置] build() { Column({ space: 20 }) { Text(基础4列网格布局).fontSize(20).fontWeight(FontWeight.Bold) Grid() { ForEach(this.gridData, (item: string) { GridItem() { Column() { // 模拟图标区域 Rect().width(50).height(50).fill(#007DFF).borderRadius(8) Text(item).fontSize(16).margin({ top: 8 }) } .width(100%) .alignItems(HorizontalAlign.Center) } }) } .columnsTemplate(1fr 1fr 1fr 1fr) // 均分4列 .columnGap(15) .rowGap(20) .width(100%) } .padding(20) } }2.2 不等宽网格布局通过不同比例fr单位实现非均等分网格适配复杂导航布局。Entry Component struct GridUnequalDemo { build() { Column({ space: 20 }) { Text(不等宽网格布局).fontSize(20).fontWeight(FontWeight.Bold) Grid() { GridItem() { Text(模块1).width(100%).height(80).textAlign(TextAlign.Center).backgroundColor(#87CEEB) } GridItem() { Text(模块2).width(100%).height(80).textAlign(TextAlign.Center).backgroundColor(#98FB98) } GridItem() { Text(模块3).width(100%).height(80).textAlign(TextAlign.Center).backgroundColor(#FFD700) } } .columnsTemplate(2fr 1fr 1fr) // 第一列宽度是后两列总和 .columnGap(10) .width(100%) } .padding(20) } }2.3 网格跨行列合并通过rowSpan、colSpan实现单元格跨行、跨列制作不规则宫格。Entry Component struct GridSpanDemo { build() { Grid() { // 跨2行 GridItem({ rowSpan: 2 }) { Text(跨行2行) .width(100%) .height(100%) .textAlign(TextAlign.Center) .backgroundColor(#FFA07A) } GridItem() { Text(普通项1).width(100%).height(80).textAlign(TextAlign.Center).backgroundColor(#DDA0DD) } GridItem() { Text(普通项2).width(100%).height(80).textAlign(TextAlign.Center).backgroundColor(#DDA0DD) } // 跨2列 GridItem({ colSpan: 2 }) { Text(跨列2列) .width(100%) .height(80) .textAlign(TextAlign.Center) .backgroundColor(#9370DB) } } .columnsTemplate(1fr 1fr 1fr) .rowGap(8) .columnGap(8) .width(100%) .padding(20) } }三、List 列表高阶用法在前文基础上拓展分组列表、下拉刷新、上拉加载三大实用功能是资讯、聊天、商品列表的核心能力。3.1 分组列表 ListItemGroup用于实现带标题的分组列表如通讯录、分类设置、多级菜单。Entry Component struct ListGroupDemo { build() { List({ space: 5 }) { // 第一组 ListItemGroup({ header: Text(常用功能).fontSize(18).fontWeight(FontWeight.Bold).padding(10) }) { ListItem() { Text(账号管理).width(100%).height(45).padding({ left: 15 }) } ListItem() { Text(安全中心).width(100%).height(45).padding({ left: 15 }) } } // 第二组 ListItemGroup({ header: Text(系统设置).fontSize(18).fontWeight(FontWeight.Bold).padding(10) }) { ListItem() { Text(消息通知).width(100%).height(45).padding({ left: 15 }) } ListItem() { Text(隐私权限).width(100%).height(45).padding({ left: 15 }) } } } .width(100%) .height(100%) } }3.2 下拉刷新 上拉加载更多结合onRefresh、onReachEnd实现列表动态刷新与分页加载模拟网络请求场景Entry Component struct ListLoadDemo { State listData: number[] [1, 2, 3, 4, 5] State isRefreshing: boolean false // 下拉刷新 onRefresh() { this.isRefreshing true setTimeout(() { this.listData [1, 2, 3, 4, 5] this.isRefreshing false }, 1500) } // 上拉加载 loadMore() { let len this.listData.length for (let i len 1; i len 5; i) { this.listData.push(i) } } build() { List({ space: 8 }) { ForEach(this.listData, (item: number) { ListItem() { Text(列表条目 ${item}) .width(100%) .height(50) .textAlign(TextAlign.Start) .padding({ left: 20 }) .backgroundColor(#F8F8F8) } }) } .width(100%) .height(100%) .refresh({ refreshing: this.isRefreshing }) .onRefresh(() this.onRefresh()) .onReachEnd(() this.loadMore()) } }四、组件懒加载LazyForEach普通ForEach会一次性渲染所有列表项数据量大时易卡顿、占用内存高。LazyForEach实现可视区域懒加载仅渲染屏幕内条目是长列表性能优化核心方案。4.1 懒加载基础使用需要自定义数据类实现ICollectionData接口适配懒加载数据源规则。// 实现懒加载数据源 class BasicDataSource implements ICollectionData { private dataArr: string[] constructor(arr: string[]) { this.dataArr arr } // 获取总数量 getTotalCount(): number { return this.dataArr.length } // 获取单条数据 getData(index: number): string { return this.dataArr[index] } // 数据变更通知 setDataChangeListener(listener: DataChangeListener): void {} } Entry Component struct LazyForEachDemo { // 模拟100条数据 private dataSource: BasicDataSource new BasicDataSource( Array.from({ length: 100 }, (_, idx) 懒加载条目 ${idx 1}) ) build() { List() { LazyForEach(this.dataSource, (item: string) { ListItem() { Text(item) .width(100%) .height(50) .padding({ left: 20 }) .backgroundColor(#F5F5F5) .margin({ bottom: 5 }) } }) } .width(100%) .height(100%) } }4.2 Grid 结合懒加载大量图片 / 宫格页面搭配LazyForEach大幅提升页面流畅度。Entry Component struct GridLazyDemo { private dataSource: BasicDataSource new BasicDataSource( Array.from({ length: 60 }, (_, idx) 宫格 ${idx 1}) ) build() { Grid() { LazyForEach(this.dataSource, (item: string) { GridItem() { Column() { Rect().width(60).height(60).fill(#4682B4).borderRadius(6) Text(item).fontSize(14).margin({ top: 6 }) } .width(100%) .alignItems(HorizontalAlign.Center) .padding(10) } }) } .columnsTemplate(1fr 1fr 1fr) .columnGap(12) .rowGap(15) .width(100%) .padding(15) } }五、综合实战相册页面Grid 懒加载整合网格布局与懒加载实现典型相册界面可直接用于项目开发。class ImageDataSource implements ICollectionData { private imgList: string[] constructor(list: string[]) { this.imgList list } getTotalCount(): number { return this.imgList.length } getData(index: number): string { return this.imgList[index] } setDataChangeListener(listener: DataChangeListener): void {} } Entry Component struct PhotoAlbum { // 模拟相册数据 albumData: ImageDataSource new ImageDataSource( Array.from({ length: 80 }, (_, i) 图片 ${i 1}) ) build() { Column() { Text(我的相册) .fontSize(24) .fontWeight(FontWeight.Bold) .padding(15) Grid() { LazyForEach(this.albumData, (name: string) { GridItem() { Stack() { Rect().width(100%).height(120).fill(#B0C4DE) Text(name).fontColor(Color.White).fontSize(14) } .width(100%) .borderRadius(6) } }) } .columnsTemplate(1fr 1fr 1fr) .columnGap(8) .rowGap(8) .layoutWeight(1) } .width(100%) .height(100%) .backgroundColor(#FFFFFF) } }六、开发总结与性能优化6.1 布局组件选用规则单列滚动列表、聊天页、资讯页优先使用List多列图标、相册、商品宫格优先使用Grid分组展示内容使用ListItemGroup快速实现分组标题。6.2 懒加载使用规范数据量超过 30 条建议使用LazyForEach替代普通ForEach图片类页面必须开启懒加载避免一次性加载大量图片造成 OOM懒加载数据源必须实现ICollectionData接口保证数据驱动正常。6.3 通用优化技巧列表 / 网格项样式尽量简化减少嵌套组件层级图片统一设置固定宽高避免动态宽高引发布局抖动下拉刷新、上拉加载增加加载状态提示提升交互体验。七、拓展方向实现瀑布流布局打造图文资讯流页面结合路由跳转实现点击列表 / 宫格项跳转到详情页学习列表侧滑删除、多选操作等高级交互。