前言
在萌宠日记的首页中,我们采用了Scroll 嵌套 Column的经典布局模式,实现了可滚动的垂直布局。这种模式是 ArkUI 中最常用的长页面布局方案,它能在有限屏幕空间内展示大量内容,同时保持流畅的滚动体验。
本文将从萌宠日记的 HomePage 布局出发,深入解析 Scroll 与 Column 的配合使用、布局参数配置、滚动性能优化,以及如何构建一个完整的可滚动首页。
一、布局架构总览
1.1 首页整体布局
┌─────────────────────────────────────┐ │ Scroll (可滚动容器) │ │ ┌─────────────────────────────────┐ │ │ │ Column (垂直布局,space: 16) │ │ │ │ ┌───────────────────────────┐ │ │ │ │ │ Header (标题栏) │ │ │ │ │ ├───────────────────────────┤ │ │ │ │ │ 宠物信息卡片 │ │ │ │ │ ├───────────────────────────┤ │ │ │ │ │ 快捷操作图标 │ │ │ │ │ ├───────────────────────────┤ │ │ │ │ │ 今日记录卡片 │ │ │ │ │ ├───────────────────────────┤ │ │ │ │ │ 健康提醒列表 │ │ │ │ │ └───────────────────────────┘ │ │ │ └─────────────────────────────────┘ │ └─────────────────────────────────────┘1.2 核心代码
// HomePage.ets — 首页布局结构 @Entry @Component export struct HomePage { build() { Scroll() { Column({ space: 16 }) { // 1. 标题栏 HeaderRow() // 2. 宠物信息卡片 PetProfileCard() // 3. 快捷操作按钮 QuickActionRow() // 4. 今日记录 TodayRecordSection() // 5. 健康提醒 HealthReminderSection() } } .width('100%') .height('100%') .backgroundColor('#FFF8F0') .scrollBar(BarState.Off) // 隐藏滚动条 } }提示:
Scroll组件内部只能有一个根组件,因此使用Column作为唯一的子组件,将多个内容区块垂直排列。这是 ArkUI 中构建可滚动页面的标准模式。
二、Scroll 组件详解
2.1 Scroll 核心属性
Scroll() { // 内容... } .width('100%') // 撑满屏幕宽度 .height('100%') // 撑满屏幕高度 .scrollBar(BarState.Off) // 隐藏滚动条 .scrollable(ScrollDirection.Vertical) // 垂直滚动(默认) .edgeEffect(EdgeEffect.Spring) // 边缘回弹效果 .onDidScroll((x: number, y: number) => { console.log(`Scrolled to: ${y}`) // 滚动事件监听 })2.2 Scroll 属性对照表
| 属性 | 类型 | 默认值 | 萌宠日记配置 | 说明 |
|---|---|---|---|---|
scrollBar | BarState | BarState.Auto | BarState.Off | 隐藏滚动条,界面更简洁 |
scrollable | ScrollDirection | Vertical | 未配置 | 默认垂直滚动 |
edgeEffect | EdgeEffect | EdgeEffect.Spring | 未配置 | 边缘回弹效果 |
onDidScroll | 回调 | — | 未配置 | 可监听滚动位置 |
enableScrollInteraction | boolean | true | 未配置 | 启用滚动交互 |
三、Column 布局详解
3.1 Column 属性
Column({ space: 16 }) { // 子组件间距 16vp // 内容区块... } .width('100%') .padding({ left: 16, right: 16 })3.2 Column 属性对照表
| 属性 | 类型 | 萌宠日记配置 | 说明 |
|---|---|---|---|
space | number | 16 | 子组件间垂直间距 |
alignItems | HorizontalAlign | 默认HorizontalAlign.Center | 水平对齐方式 |
justifyContent | FlexAlign | 默认FlexAlign.Start | 垂直对齐方式 |
width | Length | '100%' | 宽度撑满 |
padding | Padding | 各区块独立设置 | 内边距 |
3.3 间距控制
Column 的space参数控制各个子组件之间的间距:
space: 16 ↓ HeaderRow ← 顶部:16px padding space 16 PetProfileCard ← 左右:16px margin space 16 QuickActionRow ← 底部:16px padding space 16 TodayRecordSection space 16 HealthReminderSection space 16 (bottom: 16)四、内容区块划分
4.1 区块拆分
首页的 5 个内容区块,每个区块独立封装:
// 区块 1: 标题栏 @Builder HeaderRow() { Row() { Text('☰').fontSize(24).fontColor('#333333') Blank() Text('萌宠日记').fontSize(20).fontWeight(FontWeight.Bold) Blank() Text('').fontSize(22) // 占位,保持对称 } .width('100%') .padding({ left: 16, right: 16, top: 8, bottom: 8 }) } // 区块 2: 宠物信息卡片 @Builder PetProfileCard() { Column() { // 宠物信息内容... } .width('100%') .backgroundColor('#FFFFFF') .borderRadius(16) .margin({ left: 16, right: 16 }) .shadow({ radius: 4, color: '#10000000', offsetY: 2 }) }4.2 区块拆分优势
| 优势 | 说明 |
|---|---|
| 可读性 | 每个区块逻辑清晰,易于理解 |
| 可维护性 | 修改单个区块不影响其他区块 |
| 可复用性 | 区块可以在其他页面复用 |
| 测试性 | 每个区块可独立测试 |
五、滚动方向与滚动条
5.1 滚动方向
// 垂直滚动(默认) Scroll() { // 内容... } .scrollable(ScrollDirection.Vertical) // 水平滚动 Scroll() { // 内容... } .scrollable(ScrollDirection.Horizontal) // 双向滚动 Scroll() { // 内容... } .scrollable(ScrollDirection.Both) // 禁用滚动 Scroll() { // 内容... } .scrollable(ScrollDirection.None)5.2 滚动条控制
// 隐藏滚动条(萌宠日记使用) Scroll() { // 内容... } .scrollBar(BarState.Off) // 显示滚动条 Scroll() { // 内容... } .scrollBar(BarState.On) // 自动显示(内容超出时显示) Scroll() { // 内容... } .scrollBar(BarState.Auto)六、边缘回弹效果
6.1 EdgeEffect 效果
// 弹性回弹(默认效果,类似 iOS) Scroll() { // 内容... } .edgeEffect(EdgeEffect.Spring) // 无回弹效果 Scroll() { // 内容... } .edgeEffect(EdgeEffect.None)| 效果 | 说明 | 用户体验 |
|---|---|---|
Spring | 弹性回弹,拖拽到边缘时有弹性效果 | 柔和、自然 |
None | 无回弹,拖拽到边缘即停止 | 硬朗、直接 |
七、滚动事件监听
7.1 滚动位置监听
@Entry @Component export struct HomePage { private scroller: Scroller = new Scroller() @State scrollPosition: number = 0 build() { Scroll(this.scroller) { Column({ space: 16 }) { // 内容... } } .onDidScroll((xOffset: number, yOffset: number) => { this.scrollPosition = yOffset // 可用于实现:顶部阴影、悬浮效果等 }) .onScrollStart(() => { console.log('Scroll started') }) .onScrollStop(() => { console.log('Scroll stopped at:', this.scrollPosition) }) } }7.2 滚动事件应用
| 事件 | 触发时机 | 应用场景 |
|---|---|---|
onDidScroll | 滚动过程中持续触发 | 记录位置、更新 UI |
onScrollStart | 滚动开始时触发 | 暂停动画 |
onScrollStop | 滚动停止时触发 | 加载更多数据 |
八、嵌套滚动问题
8.1 滚动冲突
当 Scroll 内部嵌套 List 或 Grid 时,可能出现滚动冲突:
// 避免嵌套滚动冲突 Scroll() { Column({ space: 16 }) { // 使用 List 设置 nestedScroll List({ space: 0 }) { // 列表项... } .nestedScroll({ scrollForward: NestedScrollMode.SELF_FIRST, scrollBackward: NestedScrollMode.SELF_FIRST }) } }8.2 萌宠日记的处理
萌宠日记的首页没有嵌套滚动冲突,因为:
- Scroll 内部直接使用 Column 和 Row,不嵌套 List/Grid
- 所有内容区块都是固定高度的 Column
- 当内容超出屏幕高度时,由外层的 Scroll 统一处理滚动
九、滚动性能优化
9.1 性能建议
- 避免过度嵌套:Scroll 内部不宜嵌套过多的容器组件
- 使用 LazyForEach:长列表使用 LazyForEach 懒加载
- 减少重绘:避免在滚动事件中频繁修改状态
- 图片优化:使用合适尺寸的图片,避免大图
9.2 性能对比
| 布局方式 | 渲染性能 | 适用场景 |
|---|---|---|
| Scroll + Column | 优秀 | 内容区块较少(≤ 10 个) |
| Scroll + List | 良好 | 动态列表数据 |
| Scroll + Grid | 良好 | 网格布局 |
| 多层嵌套 | 较差 | 避免使用 |
十、最佳实践
10.1 Scroll 布局设计原则
有序列表 — Scroll 布局的 5 个原则:
- 单一根节点:Scroll 内部只能有一个根组件,通常使用 Column
- 合理间距:使用 Column 的 space 参数控制区块间距
- 统一边距:左右边距保持统一,推荐 16vp
- 隐藏滚动条:移动端通常隐藏滚动条,界面更简洁
- 避免嵌套:尽量避免 Scroll 嵌套 Scroll,会造成滚动冲突
10.2 萌宠日记的布局配置总结
| 配置项 | 值 | 说明 |
|---|---|---|
| 外层容器 | Scroll | 可滚动容器 |
| 内部容器 | Column | 垂直排列 |
| 间距 | 16vp | 区块间间距 |
| 滚动条 | BarState.Off | 隐藏 |
| 滚动方向 | Vertical | 垂直滚动 |
| 背景色 | #FFF8F0 | 页面主背景色 |
| 内容区块 | 5 个 | 标题、宠物、操作、记录、提醒 |
总结
本文从萌宠日记的首页布局结构出发,深入解析了Scroll 嵌套 Column的完整实现:
- 布局架构:Scroll 作为可滚动容器,Column 作为垂直排列容器
- Scroll 组件:核心属性、滚动方向、滚动条控制、边缘回弹
- Column 布局:间距控制、对齐方式、内边距
- 内容区块:5 个区块的拆分与封装
- 滚动事件:位置监听、滚动开始/停止事件
- 嵌套滚动:避免滚动冲突的策略
- 性能优化:减少嵌套、懒加载、图片优化
- 最佳实践:布局设计原则和配置总结
Scroll 嵌套 Column 是 ArkUI 中最基础的布局模式,掌握它能为构建更复杂的页面打下坚实基础。
下一篇我们将深入宠物信息卡片设计与阴影效果,解析卡片的视觉设计细节。
如果这篇文章对你有帮助,欢迎点赞👍、收藏⭐、关注🔔,你的支持是我持续创作的动力!
相关资源:
- Scroll 组件参考:https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-container-scroll
- Column 组件参考:https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-container-column
- ArkUI 布局基础:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkui-layout
- 滚动容器开发指导:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/scroll-container
- 边缘回弹效果:https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-container-scroll
- 嵌套滚动冲突解决:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/nested-scroll
- 性能优化概述:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/performance-optimization
- 响应式布局指导:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/responsive-layout