HarmonyOS ArkUI Scroll 组件完全指南
文章目录前言一、Scroll 基础用法1.1 最简单的 Scroll1.2 本项目中的 Scroll 使用二、Scroll 的核心属性2.1 滚动方向2.2 滚动条样式2.3 边缘效果三、用 Scroller 编程式控制滚动3.1 创建并绑定 Scroller3.2 常用 Scroller API四、水平滚动TabBar 横向菜单4.1 实现分类横向滚动五、Scroll vs List如何选择总结前言当页面内容超出屏幕高度时就需要滚动容器来承载。HarmonyOS ArkUI 提供了Scroll和List两种主要的滚动组件。很多初学者傻傻分不清楚什么时候该用哪个。本篇聚焦Scroll组件的深入用法并明确它与List的边界。一、Scroll 基础用法1.1 最简单的 ScrollEntryComponentstruct BasicScrollDemo{privateitems:number[][0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19];build(){// Scroll 只能有一个直接子节点Scroll(){Column({space:12}){// 模拟大量内容ForEach(this.items,(index:number){Row(){Text(第${index1}行内容).fontSize(15).fontColor(#333333)}.width(100%).height(56).padding({left:16,right:16}).backgroundColor(index%20?#FFFFFF:#F8F9FA).borderRadius(8)})}.padding({left:16,right:16,top:8,bottom:8}).width(100%)}.width(100%).height(100%).scrollable(ScrollDirection.Vertical)// 垂直滚动默认.scrollBar(BarState.Auto)// 自动显隐滚动条.edgeEffect(EdgeEffect.Fade)// 边缘回弹效果渐隐}}1.2 本项目中的 Scroll 使用GasStationPage.ets的bindBuilder()中用了 ScrollBuilderbindBuilder(){Column(){Scroll(){if(this.stationInfoListthis.stationInfoList.length0){List(){ForEach(this.stationInfoList,(station:StationData){ListItem(){Row({space:Constants.SPACE_12}){this.stationInfoCard(station);}.width(Constants.FULL_PERCENT);};},(station:StationData)station.idstation.name)}.width(Constants.FULL_PERCENT);}}.backgroundColor($r(app.color.start_window_background)).borderRadius(Constants.BORDER_RADIUS).margin({left:Constants.MARGIN_LEFT_16,right:Constants.MARGIN_RIGHT_16}).scrollable(ScrollDirection.Vertical).edgeEffect(EdgeEffect.Fade).scrollBar(BarState.Off)// 关闭滚动条.layoutWeight(Constants.ONE).height(Constants.MY_BUILDER_HEIGHT)}.height(Constants.MY_BUILDER_COLUMN_HEIGHT);}提示项目中用了Scroll嵌套List的结构是因为bindSheet的高度是动态的外层 Scroll 负责整体滚动控制内层 List 负责数据项渲染。二、Scroll 的核心属性2.1 滚动方向Scroll(){// ...内容}.scrollable(ScrollDirection.Vertical)// 垂直滚动默认.scrollable(ScrollDirection.Horizontal)// 水平滚动.scrollable(ScrollDirection.Free)// 自由滚动双向.scrollable(ScrollDirection.None)// 禁止滚动2.2 滚动条样式Scroll(){/* ... */}.scrollBar(BarState.Auto)// 滚动时显示停止后隐藏.scrollBar(BarState.On)// 始终显示.scrollBar(BarState.Off)// 始终隐藏项目中使用.scrollBarColor(#1A6FF5)// 滚动条颜色.scrollBarWidth(4)// 滚动条宽度2.3 边缘效果效果说明适用场景EdgeEffect.Spring弹簧回弹iOS 风格体验EdgeEffect.Fade边缘渐隐Android 风格项目中使用EdgeEffect.None无效果列表不需要回弹时三、用 Scroller 编程式控制滚动3.1 创建并绑定 ScrollerEntryComponentstruct ScrollControlDemo{// 创建 Scroller 控制器privatescroller:ScrollernewScroller();StatescrollY:number0;StateshowBackTop:booleanfalse;privateitems:number[][0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19];build(){Stack(){Scroll(this.scroller){// 绑定控制器Column({space:12}){ForEach(this.items,(index:number){Column({space:4}){Text(加油站${index1}).fontSize(16).fontWeight(FontWeight.Medium)Text(北京市海淀区 · 距您 1.2km).fontSize(13).fontColor(#999999)}.width(100%).padding(16).backgroundColor(#FFFFFF).borderRadius(12).alignItems(HorizontalAlign.Start)})}.padding(16).width(100%)}.width(100%).height(100%).scrollBar(BarState.Off).onScroll((xOffset:number,yOffset:number){// 监听滚动位置this.scrollYyOffset;this.showBackTopthis.scrollY300;// 滚动超过300时显示回顶按钮})// 回到顶部按钮浮层if(this.showBackTop){Button(↑).width(44).height(44).borderRadius(22).backgroundColor(#1A6FF5).fontColor(#FFFFFF).fontSize(20).onClick((){// 动画滚动到顶部this.scroller.scrollTo({xOffset:0,yOffset:0,animation:{duration:300,curve:Curve.EaseOut}});this.scrollY0;}).position({right:16,bottom:80})}}.width(100%).height(100%)}}3.2 常用 Scroller API方法说明scrollTo({ xOffset, yOffset })滚动到指定位置scrollBy(dx, dy)相对滚动当前位置基础上scrollEdge(Edge.Bottom)滚动到边缘顶部/底部currentOffset()获取当前滚动偏移量isAtEnd()是否已滚动到底部四、水平滚动TabBar 横向菜单4.1 实现分类横向滚动EntryComponentstruct HorizontalScrollDemo{StateselectedIndex:number0;privatecategories:string[][全部,中国石化,中国石油,壳牌,道达尔,BP石油,中海油,昆仑能源];build(){Column({space:16}){// 横向滚动分类栏Scroll(){Row({space:8}){ForEach(this.categories,(cat:string,index:number){Text(cat).fontSize(14).fontColor(this.selectedIndexindex?#FFFFFF:#666666).padding({left:16,right:16,top:8,bottom:8}).backgroundColor(this.selectedIndexindex?#1A6FF5:#F0F0F0).borderRadius(20).onClick((){this.selectedIndexindex;})})}.padding({left:16,right:16})}.scrollable(ScrollDirection.Horizontal).scrollBar(BarState.Off).width(100%)// 内容区Text(当前分类${this.categories[this.selectedIndex]}).fontSize(16).fontColor(#333333).padding(16)}.width(100%).padding({top:16})}}五、Scroll vs List如何选择需要滚动的内容类型 │ ├── 数量固定、内容多样混合布局────→ Scroll │ ├── 数量巨大1000条以上──────────→ List虚拟化 │ ├── 需要分组标题、侧边索引栏 ────────→ List │ └── 数量有限100条且布局一致 ──→ List 或 Scroll 均可特性ScrollList子节点任意一个通常是 Column只能是 ListItem虚拟化❌ 全量渲染✅ 只渲染可见项分组头❌ 需自己实现✅ ListItemGroup大数据量⚠️ 慎用✅ 推荐总结Scroll是 ArkUI 中最通用的滚动容器适合内容固定、布局混合的场景通过Scroller控制器可以实现回到顶部、自动滚动等编程式控制。对于大量同类数据的渲染推荐使用List下一篇 List 深入讲解。掌握scrollable、edgeEffect、scrollBar三个核心属性加上onScroll事件监听你就能应对绝大多数滚动场景。