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

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等专用滚动组件获得更好的性能。

http://www.xdnf.cn/news/2033.html

相关文章:

  • 制作一款打飞机游戏22:表格导出
  • Mysql唯一性约束
  • 重生之--js原生甘特图实现
  • 从LLM到AI Agent的技术演进路径:架构解析与实现逻辑
  • 图解YOLO(You Only Look Once)目标检测(v1-v5)
  • QuecPython+GNSS:实现快速定位
  • Kafka Tool(Offset Explorer)国内下载: Kafka可视化连接工具
  • Vue选项式 API 与组合式 API
  • Docker容器持久化
  • 认识 Linux 内存构成:Linux 内存调优之页表、TLB、缺页异常、大页认知
  • Ubuntu中的防火墙工具
  • 实战!银河麒麟 KYSEC 安全中心执行控制高级配置指南
  • 苹果新规生效:即日起不再接受iOS 17 SDK编译的应用提交
  • BEVPoolv2:A Cutting-edge Implementation of BEVDet Toward Deployment
  • 16.ArkUI Toggle的介绍和使用
  • UML 活动图详解之网络媒体教学系统活动图分析
  • Memcached 主主复制架构搭建与 Keepalived 高可用实现
  • OpenCV 图形API(64)图像结构分析和形状描述符------在图像中查找轮廓函数findContours()
  • vue2实现Blod文件流下载
  • 使用ACME给动态域名下的Synology NAS免费申请SSL证书(无需开放80/443端口)
  • Docker拉取镜像代理配置实践与经验分享
  • 「Java EE开发指南」如何使用MyEclipse的可视化JSF编辑器设计JSP?(一)
  • SQLAlchemy 2.x 异步查询方法比较
  • Android 14 修改侧滑手势动画效果
  • xfce桌面汉化设置
  • 【防火墙 pfsense】2配置
  • 豆瓣图书数据采集与可视化分析(三)- 豆瓣图书数据统计分析
  • OSPF网络协议
  • Antd Modal Drawer 更改默认项
  • WSL 安装过程整理