当前位置: 首页 > news >正文

12.ArkUI Scroll的介绍和使用

ArkUI Scroll 组件介绍与使用指南

什么是 Scroll 组件?

Scroll 是 ArkUI 中的滚动容器组件,当子组件内容超过容器大小时,可以提供滚动查看功能。Scroll 支持垂直和水平滚动,是构建长列表、可滚动内容区域的核心组件。

Scroll 的基本属性

  1. scrollable:设置滚动方向

    • ScrollDirection.Vertical(默认):垂直滚动
    • ScrollDirection.Horizontal:水平滚动
    • ScrollDirection.None:禁止滚动
  2. scrollBar:设置滚动条显示策略

    • BarState.Auto(默认):自动显示/隐藏
    • BarState.On:始终显示
    • BarState.Off:始终隐藏
  3. edgeEffect:设置边缘效果

    • EdgeEffect.Spring(默认):弹性效果
    • EdgeEffect.Fade:渐隐效果
    • EdgeEffect.None:无效果
  4. onScroll:滚动事件回调

    • (xOffset: number, yOffset: number) => void
  5. onScrollEdge:滚动到边缘事件回调

    • (side: Edge) => void
  6. onScrollStart/onScrollStop:滚动开始/结束事件回调

基本使用方法

垂直滚动示例

@Entry
@Component
struct VerticalScrollExample {private data: string[] = ['Item 1', 'Item 2', 'Item 3', 'Item 4', 'Item 5', 'Item 6', 'Item 7', 'Item 8']build() {Scroll() {Column() {ForEach(this.data, (item) => {Text(item).width('90%').height(100).backgroundColor('#f0f0f0').margin({ top: 10 }).textAlign(TextAlign.Center).fontSize(18)})}.width('100%')}.scrollBar(BarState.On).edgeEffect(EdgeEffect.Spring).height('100%')}
}

水平滚动示例

@Entry
@Component
struct HorizontalScrollExample {private colors: string[] = ['#ffcccc', '#ccffcc', '#ccccff', '#ffffcc', '#ffccff', '#ccffff']build() {Scroll({ scrollable: ScrollDirection.Horizontal }) {Row() {ForEach(this.colors, (color) => {Column() {Text('水平项目').fontSize(16).margin(10)}.width(150).height(100).backgroundColor(color).margin(10).borderRadius(8)})}.height(120)}.scrollBar(BarState.Auto).margin(10)}
}

高级用法

嵌套滚动

@Entry
@Component
struct NestedScrollExample {private sections: { title: string, items: string[] }[] = [{ title: 'Section 1', items: ['A1', 'A2', 'A3', 'A4'] },{ title: 'Section 2', items: ['B1', 'B2', 'B3'] },{ title: 'Section 3', items: ['C1', 'C2', 'C3', 'C4', 'C5'] }]build() {Scroll() {Column() {ForEach(this.sections, (section) => {Column() {// 分区标题Text(section.title).fontSize(20).fontWeight(FontWeight.Bold).margin({ top: 20, bottom: 10 })// 水平滚动的内容Scroll({ scrollable: ScrollDirection.Horizontal }) {Row() {ForEach(section.items, (item) => {Text(item).width(120).height(80).backgroundColor('#e0e0e0').margin(5).textAlign(TextAlign.Center).fontSize(16)})}.height(100)}.height(110).scrollBar(BarState.Off)}})}.width('100%')}.scrollBar(BarState.On).height('100%')}
}

滚动事件监听

@Entry
@Component
struct ScrollEventExample {@State scrollY: number = 0@State isScrolling: boolean = falsebuild() {Column() {Text(`滚动位置: ${this.scrollY.toFixed(0)}`).fontSize(16).margin(10)Text(this.isScrolling ? '滚动中...' : '静止').fontSize(16).margin(10)Scroll() {Column() {ForEach(Array.from({ length: 50 }), (_, index) => {Text(`列表项 ${index + 1}`).width('90%').height(60).backgroundColor(index % 2 === 0 ? '#f5f5f5' : '#ffffff').margin(5).textAlign(TextAlign.Center)})}.width('100%')}.onScroll((xOffset: number, yOffset: number) => {this.scrollY = yOffset}).onScrollStart(() => {this.isScrolling = true}).onScrollStop(() => {this.isScrolling = false}).height('80%')}.width('100%').height('100%')}
}

滚动到指定位置

@Entry
@Component
struct ScrollToExample {private scrollController: ScrollController = new ScrollController()@State targetIndex: number = 1private items: string[] = ['红色', '橙色', '黄色', '绿色', '蓝色', '靛蓝', '紫色']build() {Column() {Row() {Button('滚动到顶部').onClick(() => {this.scrollController.scrollTo(0)})Button(`滚动到 ${this.targetIndex + 1}`).onClick(() => {this.scrollController.scrollTo(this.targetIndex * 100) // 假设每项高度100this.targetIndex = (this.targetIndex + 1) % this.items.length})}.margin(10)Scroll(this.scrollController) {Column() {ForEach(this.items, (item, index) => {Column() {Text(item).fontSize(20).fontColor(Color.White)}.width('90%').height(100).backgroundColor(this.getColor(item)).margin(5).borderRadius(8)})}.width('100%')}.height('80%')}.width('100%').height('100%')}private getColor(name: string): Color {const colors: Record<string, Color> = {'红色': Color.Red,'橙色': Color.Orange,'黄色': Color.Yellow,'绿色': Color.Green,'蓝色': Color.Blue,'靛蓝': Color.Indigo,'紫色': Color.Purple}return colors[name] || Color.Grey}
}

实际应用示例

聊天界面

@Entry
@Component
struct ChatExample {@State messages: { text: string, isMe: boolean }[] = [{ text: '你好!', isMe: false },{ text: '你好,有什么可以帮您的?', isMe: true },{ text: '我想咨询产品信息', isMe: false },{ text: '我们有多款产品,您对哪类感兴趣?', isMe: true },{ text: '运动鞋系列', isMe: false },{ text: '我们最新推出了AirMax系列...', isMe: true }]build() {Column() {// 消息列表Scroll() {Column() {ForEach(this.messages, (msg, index) => {Row() {if (msg.isMe) {Text(msg.text).fontSize(16).padding(10).backgroundColor('#e3f2fd').borderRadius(8).maxWidth('70%')} else {Text(msg.text).fontSize(16).padding(10).backgroundColor('#f1f1f1').borderRadius(8).maxWidth('70%')}}.justifyContent(msg.isMe ? FlexAlign.End : FlexAlign.Start).width('100%').margin({ top: index === 0 ? 10 : 5, bottom: 5 })})}.width('100%').padding(10)}.layoutWeight(1)// 输入区域Row() {TextInput({ placeholder: '输入消息...' }).layoutWeight(1).height(40).margin(5)Button('发送').width(80).height(40).margin(5)}.width('100%').padding(5).backgroundColor('#ffffff')}.width('100%').height('100%').backgroundColor('#f5f5f5')}
}

商品详情页

@Entry
@Component
struct ProductDetailExample {@State currentImageIndex: number = 0private images: string[] = ['image1', 'image2', 'image3', 'image4']build() {Scroll() {Column() {// 图片轮播Swiper(this.currentImageIndex) {ForEach(this.images, (img) => {Image(img).width('100%').height(300).objectFit(ImageFit.Cover)})}.indicator(true).height(300).loop(true).autoPlay(true).interval(3000)// 商品信息Column() {Text('高端智能手表 Pro X').fontSize(22).fontWeight(FontWeight.Bold).margin({ top: 15, bottom: 5 })Row() {Text('¥1299').fontSize(20).fontColor('#ff0000')Text('¥1599').fontSize(14).fontColor('#999999').decoration({ type: TextDecorationType.LineThrough }).margin({ left: 10 })}.margin({ bottom: 10 })Text('销量: 1254件 | 库存: 充足').fontSize(14).fontColor('#666666').margin({ bottom: 15 })Divider()// 商品详情Text('商品详情').fontSize(18).fontWeight(FontWeight.Bold).margin({ top: 10, bottom: 10 })Text('高端智能手表 Pro X 采用最新技术,支持心率监测、血氧检测、睡眠分析等功能。1.5英寸AMOLED显示屏,IP68防水等级,30天超长续航。').fontSize(15).margin({ bottom: 20 })Image('product_detail').width('100%').aspectRatio(1.5).margin({ bottom: 20 })}.padding(15)}}.scrollBar(BarState.Off).height('100%')}
}

性能优化建议

  1. 避免过度嵌套:尽量减少Scroll内部的嵌套层级
  2. 使用LazyForEach:对于超长列表,使用LazyForEach代替ForEach
  3. 分页加载:实现滚动到底部加载更多功能,避免一次性加载过多数据
  4. 图片优化:使用合适的图片尺寸和压缩格式
  5. 减少动态效果:在滚动区域减少复杂动画和频繁的状态更新
  6. 合理使用缓存:对于复杂子组件,考虑使用@Reusable装饰器

Scroll组件是构建可滚动界面的基础,合理使用可以创建流畅的用户体验。在复杂场景中,可以结合List、Grid等专用滚动组件获得更好的性能。

相关文章:

  • C语言大写转小写2.0
  • 《软件设计师》复习笔记(4.4)——数据库新技术、SQL语言
  • vscode切换Python环境
  • 每日算法-250425
  • 【计算机视觉】CV实践- 基于PaddleSeg的遥感建筑变化检测全解析:从U-Net 3+原理到工程实践
  • Linux的多进程开发与信号处理
  • 【金仓数据库征文】-《深入探索金仓数据库:从基础到实战》
  • 【Qt】文件
  • 2025上海车展:赛轮思AI携手行业领军企业展示xUI——混合式、智能体化的AI助理平台
  • 漏洞管理体系:从扫描评估到修复验证的全生命周期实践
  • RocketMQ 主题与队列的协同作用解析(既然队列存储在不同的集群中,那要主题有什么用呢?)---管理命令、配置安装
  • Spring知识点总结
  • Vue3文件上传组件实战:打造高效的Element Plus上传解决方案,可以对文件进行删除,查看,下载功能。
  • 【HTTP/2:信息高速公路的革命】
  • C++中的vector和list的区别与适用场景
  • 西门子触摸屏文本显示不全,传送字体文件到屏幕的具体操作方法
  • C++ 日志系统实战第三步:熟悉掌握各种设计模式
  • 信令与流程分析
  • 界面控件DevExpress WinForms v25.1 - 数据处理功能持续增强
  • freecad参数化三维模型装配体解析至web端,切换参数组或修改参数
  • 对外投资增长、消费市场持续升温,中国经济砥砺前行
  • 从息屏24小时到息屏1小时,姚明在深圳开启落地试点
  • 证券时报:落实“非禁即入” ,让创新活力充分涌流
  • 见微知沪|最大力度消费补贴,最大程度满足人们对美好生活的向往
  • 为博流量编造上海车展谣言,造谣者被公安机关依法行政处罚
  • 北京顺义潮白河大桥主跨坍塌原因公布,已成立事故调查组