HarmonyOS应用开发实战:萌宠日记 - Scroll嵌套Column
·

前言
在 萌宠日记 的 首页 中,我们采用了 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
更多推荐



所有评论(0)