●VON 2025-11-22 18:15:26 发布前言
在掌握了 Column、Row 和 Stack 这三大基础布局后,我们已经能够构建静态页面结构。然而,真实应用中大量内容是动态的、可滚动的、数量不确定的——比如商品列表、新闻资讯、相册图集等。这时,就需要 ArkUI 提供的高级布局容器:List(列表布局)、Grid(网格布局)和 Scroll(滚动布局)。
本文将深入讲解这三类组件的核心用法,重点聚焦于 数据驱动渲染、item 布局定制、事件响应处理,并通过“商品列表”和“图片画廊”两个典型场景,带你掌握鸿蒙应用中高频出现的动态 UI 实现方式。
一、List:高性能列表布局
List 是用于展示纵向或横向滚动列表的容器,专为大量数据项优化,支持懒加载、复用机制,性能远优于手动用 Column + Scroll 拼接。
1. 基本语法与数据绑定
@Entry
@Component
struct ProductListPage {
// 模拟商品数据
private products: Array<{ id: number; name: string; price: number }> = [
{ id: 1, name: '无线耳机', price: 299 },
{ id: 2, name: '智能手表', price: 1299 },
{ id: 3, name: '平板电脑', price: 2499 },
// ...更多数据
];
build() {
List({ space: 12 }) {
ForEach(this.products, (item) => {
ListItem() {
this.ProductItem(item);
}
}, item => item.id.toString()) // key 值,提升渲染性能
}
.width('100%')
.height('100%')
.padding(16)
}
@Builder
ProductItem(item: { id: number; name: string; price: number }) {
Row() {
Image($r('app.media.product_default'))
.width(80)
.height(80)
.borderRadius(8)
Column() {
Text(item.name)
.fontSize(16)
.fontWeight(FontWeight.Medium)
Text(`¥${item.price}`)
.fontSize(14)
.fontColor('#e54d42')
.margin({ top: 4 })
}
.layoutWeight(1)
.alignItems(HorizontalAlign.Start)
}
.width('100%')
.padding(12)
.backgroundColor('#fff')
.borderRadius(10)
.onClick(() => {
console.log(`点击了商品:${item.name}`);
// 可跳转详情页
})
}
}
2. 关键特性说明
ForEach:用于遍历数据源,必须提供唯一key(如item.id),确保高效更新;ListItem():List 的子项容器,不可省略;@Builder:将 item UI 封装为可复用构建器,提升代码可读性;- 事件处理:直接在
ListItem或内部组件上绑定.onClick()。
✅ 适用场景:消息列表、订单记录、设置菜单、新闻流等。
二、Grid:灵活网格布局
Grid 用于展示二维网格结构,常用于相册、商品橱窗、图标面板等场景。支持行列数动态配置、间距控制、滚动方向设置。
1. 基本用法:图片画廊
@Entry
@Component
struct PhotoGallery {
private images: string[] = [
$r('app.media.photo1'),
$r('app.media.photo2'),
$r('app.media.photo3'),
// ...共12张
];
build() {
Grid() {
ForEach(this.images, (imgSrc, index) => {
GridItem() {
Image(imgSrc)
.objectFit(ImageFit.Cover) // 图片填充模式
.width('100%')
.height('100%')
}
.aspectRatio(1) // 保持 1:1 宽高比
}, item => index.toString())
}
.columnsTemplate('1fr 1fr 1fr') // 三列等宽
.rowsTemplate('repeat(auto-fill, 120px)') // 行高固定120px
.columnsGap(8)
.rowsGap(8)
.width('100%')
.height('100%')
.padding(8)
}
}
2. 核心属性解析
| 属性 | 说明 |
|---|---|
columnsTemplate | 列模板,如 '1fr 1fr' 表示两列等宽 |
rowsTemplate | 行模板,常用 repeat(auto-fill, 100px) 自动换行 |
columnsGap / rowsGap | 列间距与行间距 |
GridItem().aspectRatio(ratio) | 设置子项宽高比(如 1 表示正方形) |
💡 技巧:使用 aspectRatio(1) 可轻松实现“正方形图片网格”,避免图片拉伸。
✅ 适用场景:相册、商品橱窗、应用图标桌面、标签云等。
三、Scroll:通用滚动容器
当内容超出屏幕范围时,Scroll 提供基础滚动能力。虽然 List 和 Grid 自带滚动,但 Scroll 更适合包裹混合布局(如图文混排长页面)。
示例:长文章详情页
Scroll() {
Column() {
Image($r('app.media.article_banner'))
.width('100%')
.height(200)
.objectFit(ImageFit.Fill)
Text('鸿蒙生态的未来展望')
.fontSize(24)
.fontWeight(FontWeight.Bold)
.margin({ top: 16, horizontal: 16 })
Text('HarmonyOS 自发布以来...')
.fontSize(16)
.lineHeight(28)
.margin({ top: 12, horizontal: 16 })
.textAlign(TextAlign.Justify)
// 可继续添加评论区、推荐文章等模块
}
}
.width('100%')
.height('100%')
.scrollable(ScrollDirection.Vertical) // 默认垂直滚动
注意事项
Scroll内部通常只有一个直接子组件(如Column);- 不适用于大量重复 item(此时应优先用
List); - 支持
.onScroll(event => {...})监听滚动位置,实现吸顶、懒加载等效果。
四、综合实战:电商首页商品区
现在,我们将结合 List 和 Grid,模拟一个电商 App 的首页片段:
Column() {
// 轮播图(此处简化)
Text('【Banner 轮播图】')
.width('100%')
.height(160)
.backgroundColor('#eee')
.textAlign(TextAlign.Center)
// 分类导航(Row)
Row() {
ForEach(['手机', '电脑', '穿戴', '家居'], (category) => {
Text(category)
.width(80)
.height(40)
.backgroundColor('#f0f0f0')
.textAlign(TextAlign.Center)
.borderRadius(20)
})
}
.space(12)
.padding({ horizontal: 16, top: 12 })
// 商品网格(热销推荐)
Text('🔥 热销推荐')
.fontSize(18)
.fontWeight(FontWeight.Bold)
.margin({ top: 16, left: 16 })
Grid() {
ForEach(this.hotProducts, (item) => {
GridItem() {
Column() {
Image($r('app.media.product_default'))
.width('100%')
.aspectRatio(1)
.borderRadius(8)
Text(item.name)
.fontSize(14)
.maxLines(1)
.textOverflow({ overflow: TextOverflow.Ellipsis })
Text(`¥${item.price}`)
.fontSize(14)
.fontColor('#e54d42')
.margin({ top: 4 })
}
.width('100%')
.padding(6)
.backgroundColor('#fff')
.borderRadius(8)
.onClick(() => {
router.pushUrl({ url: `pages/ProductDetail?id=${item.id}` });
})
}
}, item => item.id.toString())
}
.columnsTemplate('1fr 1fr 1fr 1fr') // 四列
.columnsGap(8)
.rowsGap(12)
.padding({ horizontal: 8, bottom: 16 })
}
.height('100%')
.backgroundColor('#f8f8f8')
🔍 设计亮点: 使用 Grid 实现四列商品网格,适配手机屏幕; 每个商品项包含图片、标题、价格,点击跳转详情; 整体嵌套在 Column 中,与其他模块(Banner、分类)组合成完整页面。
五、性能与最佳实践
⚠️ 避免常见陷阱
不要在 ForEach 中直接写复杂逻辑,应提取为@Builder;- 确保 key 唯一且稳定,避免使用数组索引(index)作为 key;
图片务必设置尺寸和 objectFit,防止布局抖动。
✅ 推荐做法
- 大量数据用
List,网格展示用Grid,混合长内容用Scroll; - 结合
LazyForEach(进阶)实现超大数据集的按需加载; - 使用
cachedCount预加载相邻 item,提升滚动流畅度。
六、小结
今天我们系统学习了 ArkUI 的三大动态布局组件:
- List:高效渲染纵向/横向列表,适合消息流、商品列表;
- Grid:灵活构建二维网格,适用于相册、图标面板;
- Scroll:通用滚动容器,用于混合内容长页面。
通过数据绑定、事件处理与布局组合,你已经具备实现主流 App 页面的能力。下一步,我们将深入 状态管理与组件通信,让你的 UI 不仅“看得见”,更能“动起来”!
🛠️ 动手练习建议: 用 List 实现一个“待办事项”列表,支持点击完成/删除; 用 Grid 构建一个“应用图标桌面”,长按可编辑; 在 Scroll 中实现一个“个人主页”,包含头像、简介、动态、关注列表等模块。
暂无评论数据
发布
相关推荐
云上修代码
2171
0
快乐编译者
1168
0
2030
0
老李的控制台
1202
0
1361
0
●VON
HarmonyOS应用开发者初级工程师、影刀初级RPA工程师、YashanDB数据库V23.2认证管理员、金仓数据库认证专员等技能证书,主持参与省级团队赛9项,个人赛2项均获得省级荣誉,其中2025年作为负责人带领团队斩获“挑战杯”全国大学生课外学术科技作品竞赛河南省省级一等奖。
帖子
提问
粉丝
鸿蒙实战:用 ArkTS 开发智能饮水助手
2025-11-25 16:27:52 发布鸿蒙实战:打造跨设备音乐播放器
2025-11-25 16:23:11 发布