HarmonyOS ArkUI训练营入门-组件掌握系列-Scroll 滚动容器组件详解-PC版本
·

概述
滚动容器是移动应用中处理超出屏幕内容的重要方式,无论是长列表、大图片还是多内容页面,都需要滚动功能来展示完整内容。HarmonyOS ArkUI 提供的 Scroll 组件功能强大,支持水平滚动、垂直滚动和双向滚动等多种模式。本文将从组件基础、滚动方向、事件处理、实际应用等多个维度,深入讲解 Scroll 组件的使用方法。
一、Scroll 组件基础
1.1 组件定义与作用
Scroll 组件用于创建可滚动的内容区域,当内容超出容器尺寸时,用户可以通过滑动查看完整内容。
@Entry
@Component
struct ScrollBasic {
build() {
Column() {
Scroll() {
Column() {
ForEach([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], (index: number) => {
Text('项目 ' + index)
.width('100%')
.height(60)
.backgroundColor('#F5F5F5')
.margin({ bottom: 8 })
})
}
}
.width('100%')
.height(300)
}
}
}
1.2 构造函数参数
Scroll 的构造函数支持以下参数:
Scroll(options?: {
scrollable?: ScrollDirection; // 滚动方向
scrollBar?: BarState; // 滚动条状态
scrollBarColor?: string; // 滚动条颜色
scrollBarWidth?: number; // 滚动条宽度
})
1.3 滚动方向
| 方向 | 说明 |
|---|---|
ScrollDirection.Vertical |
垂直滚动 |
ScrollDirection.Horizontal |
水平滚动 |
ScrollDirection.None |
禁止滚动 |
二、垂直滚动
2.1 基础垂直滚动
垂直滚动是最常用的滚动方式:
@Entry
@Component
struct VerticalScrollDemo {
build() {
Column() {
Scroll() {
Column() {
ForEach([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], (index: number) => {
Row() {
Text('项目 ' + index)
.fontSize(16)
.layoutWeight(1)
Text('内容 ' + index)
.fontSize(14)
.fontColor('#999999')
}
.width('100%')
.height(60)
.padding(16)
.backgroundColor(index % 2 === 0 ? '#FFFFFF' : '#F8F8F8')
})
}
}
.width('100%')
.height(300)
.scrollBar(BarState.On)
}
}
}
2.2 滚动条设置
通过 scrollBar 属性设置滚动条显示状态:
@Entry
@Component
struct ScrollBarDemo {
build() {
Column() {
Text('显示滚动条')
.fontSize(14)
.margin({ bottom: 8 })
Scroll() {
Column() {
ForEach([1, 2, 3, 4, 5, 6], (index: number) => {
Text('项目 ' + index)
.width('100%')
.height(60)
.backgroundColor('#F5F5F5')
})
}
}
.width('100%')
.height(200)
.scrollBar(BarState.On)
.scrollBarColor('#0A59F7')
.scrollBarWidth(4)
.margin({ bottom: 16 })
Text('隐藏滚动条')
.fontSize(14)
.margin({ bottom: 8 })
Scroll() {
Column() {
ForEach([1, 2, 3, 4, 5, 6], (index: number) => {
Text('项目 ' + index)
.width('100%')
.height(60)
.backgroundColor('#F5F5F5')
})
}
}
.width('100%')
.height(200)
.scrollBar(BarState.Off)
}
}
}
三、水平滚动
3.1 基础水平滚动
通过 direction 属性设置水平滚动:
@Entry
@Component
struct HorizontalScrollDemo {
build() {
Column() {
Scroll({ direction: ScrollDirection.Horizontal }) {
Row() {
ForEach([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], (index: number) => {
Column() {
Text('卡片 ' + index)
.fontSize(14)
}
.width(100)
.height(80)
.backgroundColor('#E8F0FE')
.borderRadius(8)
.alignItems(HorizontalAlign.Center)
.justifyContent(FlexAlign.Center)
.margin({ right: 12 })
})
}
.padding(12)
}
.width('100%')
.height(100)
}
}
}
3.2 滚动条状态
| 状态 | 说明 |
|---|---|
BarState.On |
常驻显示 |
BarState.Off |
隐藏 |
BarState.Auto |
滚动时显示 |
四、事件处理
4.1 滚动事件监听
通过 onScroll 事件监听滚动位置:
@Entry
@Component
struct ScrollEventDemo {
@State scrollPosition: number = 0;
build() {
Column() {
Text('滚动位置: ' + Math.round(this.scrollPosition) + 'px')
.fontSize(14)
.fontColor('#999999')
.margin({ bottom: 8 })
Scroll() {
Column() {
ForEach([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], (index: number) => {
Text('项目 ' + index)
.width('100%')
.height(60)
.backgroundColor('#F5F5F5')
})
}
}
.width('100%')
.height(300)
.onScroll((xOffset: number, yOffset: number) => {
this.scrollPosition = yOffset;
})
}
}
}
4.2 滚动到边缘事件
通过 onScrollEdge 事件监听滚动到边缘:
@Entry
@Component
struct ScrollEdgeDemo {
@State edgeStatus: string = '未到达边缘';
build() {
Column() {
Text('边缘状态: ' + this.edgeStatus)
.fontSize(14)
.fontColor('#999999')
.margin({ bottom: 8 })
Scroll() {
Column() {
ForEach([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], (index: number) => {
Text('项目 ' + index)
.width('100%')
.height(60)
.backgroundColor('#F5F5F5')
})
}
}
.width('100%')
.height(300)
.onScrollEdge((side: Edge) => {
if (side === Edge.Top) {
this.edgeStatus = '到达顶部';
} else if (side === Edge.Bottom) {
this.edgeStatus = '到达底部';
}
})
}
}
}
五、实际案例:滚动容器演示
5.1 需求分析
构建一个滚动容器演示页面,包含:
- 垂直滚动演示
- 水平滚动演示
- 滚动方向切换
- 滚动位置显示
5.2 代码实现
import { router } from '@kit.ArkUI';
@Entry
@Component
struct ScrollDemo {
@State scrollPosition: number = 0;
@State scrollDirection: number = 0;
build() {
Column() {
Row() {
Button('返回')
.onClick(() => {
router.back();
})
Text('Scroll 组件演示')
.fontSize(20)
.fontWeight(FontWeight.Bold)
.layoutWeight(1)
.textAlign(TextAlign.Center)
}
.width('100%')
.padding(12)
.backgroundColor('#F1F3F5')
Column() {
Text('垂直滚动演示')
.fontSize(16)
.fontWeight(FontWeight.Bold)
.margin({ top: 20, bottom: 12 })
.width('90%')
Scroll() {
Column() {
ForEach([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], (index: number) => {
Row() {
Text('项目 ' + index)
.fontSize(16)
.fontColor('#333333')
.layoutWeight(1)
Text('内容 ' + index)
.fontSize(14)
.fontColor('#999999')
}
.width('100%')
.height(60)
.padding({ left: 16, right: 16 })
.backgroundColor(index % 2 === 0 ? '#FFFFFF' : '#F8F8F8')
.alignItems(VerticalAlign.Center)
})
}
.width('100%')
}
.width('90%')
.height(200)
.backgroundColor('#FFFFFF')
.borderRadius(8)
.borderWidth(1)
.borderColor('#E5E5E5')
.onScroll((xOffset: number, yOffset: number) => {
this.scrollPosition = yOffset;
})
Text('滚动位置: ' + Math.round(this.scrollPosition) + 'px')
.fontSize(12)
.fontColor('#999999')
.margin({ top: 8 })
Text('水平滚动演示')
.fontSize(16)
.fontWeight(FontWeight.Bold)
.margin({ top: 24, bottom: 12 })
.width('90%')
Scroll({ direction: ScrollDirection.Horizontal }) {
Row() {
ForEach([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], (index: number) => {
Column() {
Text('卡片 ' + index)
.fontSize(14)
.fontColor('#333333')
}
.width(100)
.height(80)
.backgroundColor('#E8F0FE')
.borderRadius(8)
.alignItems(HorizontalAlign.Center)
.justifyContent(FlexAlign.Center)
.margin({ right: 12 })
})
}
.padding(12)
}
.width('90%')
.height(100)
.backgroundColor('#FFFFFF')
.borderRadius(8)
.borderWidth(1)
.borderColor('#E5E5E5')
Text('滚动方向设置')
.fontSize(16)
.fontWeight(FontWeight.Bold)
.margin({ top: 24, bottom: 12 })
.width('90%')
Column() {
Row() {
Button('垂直滚动')
.layoutWeight(1)
.height(40)
.backgroundColor(this.scrollDirection === 0 ? '#0A59F7' : '#F1F3F5')
.fontColor(this.scrollDirection === 0 ? '#FFFFFF' : '#333333')
.onClick(() => {
this.scrollDirection = 0;
})
Button('水平滚动')
.layoutWeight(1)
.height(40)
.margin({ left: 8 })
.backgroundColor(this.scrollDirection === 1 ? '#0A59F7' : '#F1F3F5')
.fontColor(this.scrollDirection === 1 ? '#FFFFFF' : '#333333')
.onClick(() => {
this.scrollDirection = 1;
})
Button('双向滚动')
.layoutWeight(1)
.height(40)
.margin({ left: 8 })
.backgroundColor(this.scrollDirection === 2 ? '#0A59F7' : '#F1F3F5')
.fontColor(this.scrollDirection === 2 ? '#FFFFFF' : '#333333')
.onClick(() => {
this.scrollDirection = 2;
})
}
}
.width('90%')
.backgroundColor('#FFFFFF')
.padding(16)
.borderRadius(8)
Text('提示:Scroll 组件支持水平、垂直和双向滚动,通过 direction 属性设置')
.fontSize(12)
.fontColor('#999999')
.margin({ top: 24 })
.width('90%')
.textAlign(TextAlign.Center)
}
.width('100%')
.layoutWeight(1)
}
.width('100%')
.height('100%')
.backgroundColor('#FFFFFF')
}
}
六、Scroll 与 List 对比
6.1 功能对比
| 特性 | Scroll | List |
|---|---|---|
| 内容类型 | 任意内容 | 列表数据 |
| 滚动方向 | 水平/垂直 | 垂直为主 |
| 懒加载 | 不支持 | 支持 |
| 适用场景 | 通用滚动 | 大数据列表 |
6.2 使用场景建议
| 场景 | 推荐组件 |
|---|---|
| 长列表数据 | List |
| 表单页面滚动 | Scroll |
| 横向卡片滚动 | Scroll |
| 大图片查看 | Scroll |
七、最佳实践
7.1 性能优化
| 建议 | 说明 |
|---|---|
| 控制内容大小 | 避免过多嵌套 |
| 合理设置高度 | 确保滚动区域正确 |
| 使用滚动条 | 提示用户可滚动 |
7.2 常见问题
| 问题 | 解决方案 |
|---|---|
| 无法滚动 | 检查内容是否超出容器 |
| 滚动条不显示 | 设置 scrollBar 属性 |
| 滚动方向错误 | 检查 direction 设置 |
八、总结
Scroll 组件是处理超出屏幕内容的重要组件,掌握其使用方法对于构建复杂页面至关重要。
核心要点:
- 使用
direction设置滚动方向 - 使用
scrollBar设置滚动条显示 - 使用
onScroll监听滚动位置 - 垂直滚动适合长内容页面
- 水平滚动适合卡片展示
希望本文能帮助你更好地理解和使用 Scroll 组件,构建出优秀的 HarmonyOS 应用。
参考资料:
更多推荐
所有评论(0)