HarmonyOS 6.1 实战:Scroll 滚动容器全面解析
前言Scroll是 ArkUI 中最基础的滚动容器当内容超过容器尺寸时自动提供滚动能力。区别于List专为列表设计Scroll支持任意布局内容的垂直/水平滚动并提供丰富的边缘效果、滚动条控制及滚动事件回调。本文通过完整示例逐一演示。运行效果初始状态垂直滚动切换水平滚动模式核心 API 一览API说明Scroll(scroller?)滚动容器可传入Scroller控制器.scrollable(ScrollDirection)滚动方向Vertical / Horizontal / Free / None.scrollBar(BarState)滚动条可见性Auto / On / Off.edgeEffect(EdgeEffect)边缘效果Spring弹性/ Fade渐隐/ None.onScroll(xOff, yOff)滚动偏移量回调.onScrollEdge(side)到达边缘时回调scroller.scrollTo({xOffset, yOffset})编程式滚动到指定位置scroller.scrollEdge(Edge.Top)滚动到顶部/底部scroller.currentOffset()获取当前滚动偏移量完整示例代码Entry Component struct Index { State scrollDir: ScrollDirection ScrollDirection.Vertical State edgeEffectIndex: number 0 State scrollOffsetY: number 0 State scrollOffsetX: number 0 State reachedEdge: string private scroller: Scroller new Scroller() private edgeEffects: EdgeEffect[] [EdgeEffect.Spring, EdgeEffect.Fade, EdgeEffect.None] private edgeLabels: string[] [Spring, Fade, None] private colorList: string[] [ #ff6b6b, #ff9f43, #feca57, #48dbfb, #ff9ff3, #54a0ff, #5f27cd, #00d2d3, #1dd1a1, #c8d6e5, #576574, #341f97, ] build() { Column({ space: 0 }) { // 控制栏 Row({ space: 0 }) { // 边缘效果选择 Row({ space: 6 }) { ForEach(this.edgeLabels, (label: string, idx: number) { Text(label) .fontSize(12) .fontColor(this.edgeEffectIndex idx ? #fff : #333) .backgroundColor(this.edgeEffectIndex idx ? #0066ff : #eeeeee) .padding({ left: 10, right: 10, top: 5, bottom: 5 }) .borderRadius(12) .onClick(() { this.edgeEffectIndex idx }) }) } .layoutWeight(1) // 方向切换 Row({ space: 6 }) { Text(垂直) .fontSize(12) .fontColor(this.scrollDir ScrollDirection.Vertical ? #fff : #333) .backgroundColor(this.scrollDir ScrollDirection.Vertical ? #0066ff : #eeeeee) .padding({ left: 10, right: 10, top: 5, bottom: 5 }) .borderRadius(12) .onClick(() { this.scrollDir ScrollDirection.Vertical this.scroller.scrollEdge(Edge.Top) }) Text(水平) .fontSize(12) .fontColor(this.scrollDir ScrollDirection.Horizontal ? #fff : #333) .backgroundColor(this.scrollDir ScrollDirection.Horizontal ? #0066ff : #eeeeee) .padding({ left: 10, right: 10, top: 5, bottom: 5 }) .borderRadius(12) .onClick(() { this.scrollDir ScrollDirection.Horizontal this.scroller.scrollEdge(Edge.Start) }) Button(回顶部) .fontSize(12) .height(32) .backgroundColor(#ff6600) .onClick(() { this.scroller.scrollEdge(Edge.Top) }) } } .width(100%) .height(52) .padding({ left: 12, right: 12 }) .backgroundColor(#f8f8f8) .border({ width: { bottom: 1 }, color: #e0e0e0 }) // 偏移量显示 Row({ space: 8 }) { Text(X: Math.round(this.scrollOffsetX).toString()) .fontSize(12).fontColor(#0066ff) Text(Y: Math.round(this.scrollOffsetY).toString()) .fontSize(12).fontColor(#ff6600) if (this.reachedEdge.length 0) { Text(到达: this.reachedEdge) .fontSize(12).fontColor(#00aa44) } } .width(100%) .height(32) .padding({ left: 16 }) // Scroll 主体 Scroll(this.scroller) { if (this.scrollDir ScrollDirection.Vertical) { // 垂直方向色块列表 Column({ space: 12 }) { ForEach(this.colorList, (color: string, idx: number) { Column() { Text(色块 (idx 1).toString()) .fontSize(18) .fontColor(#ffffff) .fontWeight(FontWeight.Bold) Text(color) .fontSize(12) .fontColor(rgba(255,255,255,0.7)) .margin({ top: 4 }) } .width(100%) .height(80) .backgroundColor(color) .borderRadius(12) .justifyContent(FlexAlign.Center) }) } .width(100%) .padding({ left: 16, right: 16 }) } else { // 水平方向横排色块 Row({ space: 12 }) { ForEach(this.colorList, (color: string, idx: number) { Column() { Text((idx 1).toString()) .fontSize(24) .fontColor(#ffffff) .fontWeight(FontWeight.Bold) Text(color) .fontSize(10) .fontColor(rgba(255,255,255,0.8)) .margin({ top: 4 }) } .width(120) .height(100%) .backgroundColor(color) .borderRadius(12) .justifyContent(FlexAlign.Center) }) } .height(100%) .padding({ top: 16, bottom: 16 }) } } .scrollable(this.scrollDir) .scrollBar(BarState.Auto) .edgeEffect(this.edgeEffects[this.edgeEffectIndex]) .onScroll((_x: number, _y: number) { let offset this.scroller.currentOffset() this.scrollOffsetX offset.xOffset this.scrollOffsetY offset.yOffset }) .onScrollEdge((side: Edge) { if (side Edge.Top) { this.reachedEdge 顶部 } else if (side Edge.Bottom) { this.reachedEdge 底部 } else if (side Edge.Start) { this.reachedEdge 左侧 } else if (side Edge.End) { this.reachedEdge 右侧 } }) .onScrollEnd(() { this.reachedEdge }) .width(100%) .layoutWeight(1) .padding({ top: 8, bottom: 8 }) } .width(100%) .height(100%) .backgroundColor(#ffffff) } }关键知识点1. Scroller 控制器编程式滚动Scroller是实现“回到顶部“、“跳转到指定位置“等功能的关键private scroller: Scroller new Scroller() // 绑定到 Scroll Scroll(this.scroller) { ... } // 编程式控制 this.scroller.scrollTo({ xOffset: 0, yOffset: 500 }) // 滚动到 y500 this.scroller.scrollEdge(Edge.Top) // 回到顶部 this.scroller.scrollEdge(Edge.Bottom) // 滚到底部 let pos this.scroller.currentOffset() // 获取当前偏移2. onScroll 回调的参数.onScroll(xOffset, yOffset)传入的是本次滚动的增量不是总偏移量。要获取当前绝对位置需调用scroller.currentOffset().onScroll((_dx: number, _dy: number) { // _dx/_dy 是增量用 currentOffset() 获取绝对位置 let pos this.scroller.currentOffset() this.currentY pos.yOffset })3. 边缘效果EdgeEffect值视觉效果适用场景EdgeEffect.Spring超出边界后弹性回弹iOS 风格最常用EdgeEffect.Fade边缘渐隐遮罩偏 Android 风格EdgeEffect.None无边缘效果硬停止精确控制场景4. 切换滚动方向切换滚动方向时需要重置滚动位置否则偏移量残留会导致内容不可见// 切换到水平方向时重置滚动位置 this.scrollDir ScrollDirection.Horizontal this.scroller.scrollEdge(Edge.Start) // 回到最左侧5. Scroll vs List 的选型维度ScrollList内容类型任意布局Column/Row/Grid 等仅列表项性能全部子节点同时渲染虚拟化只渲染可见项适用数据量较少100 项任意千级以上分组吸顶不支持支持ListItemGroup小结Scroll适合内容数量有限的任意布局滚动场景不具备虚拟化能力通过Scroller控制器可以编程式滚动到任意位置onScroll回调参数是增量绝对位置需用scroller.currentOffset()获取edgeEffect选Spring最接近系统原生体验长列表数量大、相似结构请使用List而非Scroll Column ForEach

相关新闻

Feed 流的排序算法:时间线、热度与个性化的融合排序

Feed 流的排序算法:时间线、热度与个性化的融合排序

Feed 流的排序算法:时间线、热度与个性化的融合排序 一、如果只按时间排序,用户看到的全是三天前的广告;如果只按热度,用户看不到朋友刚发的动态 Feed 流排序是一个经典的"三维决策"问题。三个维度分别是:时…

2026/7/22 0:13:32 阅读更多 →
小程序毕设项目:基于 SpringBoot 的供应链采购供货数据统计平台 商品货源配送与供货运维小程序 (源码+文档,讲解、调试运行,定制等)

小程序毕设项目:基于 SpringBoot 的供应链采购供货数据统计平台 商品货源配送与供货运维小程序 (源码+文档,讲解、调试运行,定制等)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/7/23 0:56:59 阅读更多 →
C++ vector模拟实现:从内存管理到现代C++特性的深度解析

C++ vector模拟实现:从内存管理到现代C++特性的深度解析

1. 项目概述:为什么我们要亲手模拟实现vector?在C的世界里,std::vector几乎是每个开发者最早接触、也最频繁使用的容器。它封装了动态数组,提供了自动内存管理、随机访问和高效的尾部增删操作。然而,对于许多开发者来说…

2026/7/23 15:55:09 阅读更多 →

最新新闻

男主多角度人设三视图关键词

男主多角度人设三视图关键词

今天分享实测适配 Image2 漫剧模型的古风男主多角度人设提示词,一套指令同时生成特写、正面、侧颜、背面三视图,完美锁定五官、发型、服饰,保证漫剧全程人物不变脸。白底三视图设定图,直接拿来当漫剧角色卡、分镜参考。👇4 位男主完整正向提示词 + 通用负面词 三视图角色…

2026/7/24 8:53:55 阅读更多 →
大模型后训练:提升安全性与领域适配的关键技术

大模型后训练:提升安全性与领域适配的关键技术

1. 大模型后训练的本质与挑战 大模型后训练(Post-Training)是指在大规模预训练完成后,针对特定任务或领域进行的二次优化过程。这个过程不同于微调(Fine-Tuning),它更注重在保持模型通用能力的基础上&#…

2026/7/24 8:53:55 阅读更多 →
大模型后训练方法论:从原理到实践的SOLID框架

大模型后训练方法论:从原理到实践的SOLID框架

1. 为什么大模型后训练需要系统化方法论?大模型后训练(Post-training)已经成为AI工程实践中不可或缺的关键环节。不同于预训练阶段追求通用能力,后训练的核心目标是让大模型适配特定场景需求。但现实情况是,许多团队在…

2026/7/24 8:53:55 阅读更多 →
Python从入门到实战(十八):协程与异步编程

Python从入门到实战(十八):协程与异步编程

目录 一、为什么需要协程 1. 回顾并发模型 2. 多线程的问题 3. 引出协程 二、什么是协程 1. 协程基本概念 2. 协程核心特点 三、async 1. async def 与协程函数 2. 协程函数与协程对象 3. 代码验证 四、await 1. await 的作用 2. 可等待对象 3. await 控制权交接…

2026/7/24 8:53:55 阅读更多 →
GELab-Zero:4B参数端侧多模态GUI Agent开源方案解析

GELab-Zero:4B参数端侧多模态GUI Agent开源方案解析

1. GELab-Zero项目概述GELab-Zero是阶跃星辰最新开源的4B参数端侧多模态GUI Agent模型,专为移动设备本地化智能交互设计。这个项目最吸引我的地方在于它首次实现了"模型基建"的完整开源方案——不仅提供了性能优异的4B轻量化模型,还配套开源了…

2026/7/24 8:53:55 阅读更多 →
YOLOv11结合DySample提升目标检测精度实践

YOLOv11结合DySample提升目标检测精度实践

1. 项目概述:YOLOv11与DySample的强强联合目标检测领域近年来最令人兴奋的进展之一,就是YOLO系列模型的持续进化。作为该系列的最新成员,YOLOv11在精度和速度的平衡上达到了新高度,但它的上采样模块仍然沿用传统的最近邻插值方法—…

2026/7/24 8:52:55 阅读更多 →

日新闻

用Highcharts 创建可拖拽三维散点立方体3D图表

用Highcharts 创建可拖拽三维散点立方体3D图表

该案例基于Highcharts scatter3d 三维散点图实现空间立方体散点可视化,核心特色:三维 X/Y/Z 三轴空间,所有散点分布在 0~10 立方体空间内;散点使用径向渐变实现立体 3D 圆球质感;支持鼠标 / 触屏拖拽画布,…

2026/7/24 0:00:29 阅读更多 →
AppCertDlls:进程创建路径上的 DLL 入口

AppCertDlls:进程创建路径上的 DLL 入口

AppCertDlls:进程创建路径上的 DLL 入口 AppCertDlls 位于 HKLM\System\CurrentControlSet\Control\Session Manager\AppCertDlls。本文的程序功能是只读列出这个键在 64 位和 32 位注册表视图中的全部值,并显示每条值的来源、名称、类型和可安全显示的数…

2026/7/24 0:00:29 阅读更多 →
我的编程之路:第一篇博客

我的编程之路:第一篇博客

大家好,我是一名编程初学者,同时这也是我编程学习之路上的第一篇博客。在这里,我想要向大家介绍我的一些想法和规划。a.自我介绍我是一个刚刚接触编程的新手,目前在学习c语言,我对编程世界充满了强烈的好奇。当然&…

2026/7/24 0:00:29 阅读更多 →

周新闻

Go语言静态资源打包方案对比与实践指南

Go语言静态资源打包方案对比与实践指南

1. 项目背景与核心需求在Go语言开发中,我们经常需要处理静态资源文件的打包问题。无论是Web应用的模板文件、前端资源,还是配置文件、证书等,都需要随程序一起分发。传统做法是将这些文件与编译后的二进制文件放在同一目录下,但这…

2026/7/24 3:59:20 阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

Go语言实现高性能LDAP认证服务的架构与实践

1. 项目背景与核心价值LDAP(轻量级目录访问协议)作为企业级身份认证的黄金标准,已经服务了超过80%的财富500强公司。我在金融科技领域实施统一认证体系时,发现传统Java方案存在启动慢、内存占用高等痛点。而Go语言凭借其协程并发模…

2026/7/24 1:23:39 阅读更多 →
【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

更多请点击: https://intelliparadigm.com 第一章:AI面试官实战指南的核心价值与适用场景 AI面试官并非替代人类HR的“黑箱工具”,而是以可解释、可审计、可迭代的方式,赋能招聘全链路的关键基础设施。其核心价值在于将主观经验沉…

2026/7/23 17:49:47 阅读更多 →

月新闻