12.ArkUI Scroll的介绍和使用
ArkUI Scroll 组件介绍与使用指南
什么是 Scroll 组件?
Scroll 是 ArkUI 中的滚动容器组件,当子组件内容超过容器大小时,可以提供滚动查看功能。Scroll 支持垂直和水平滚动,是构建长列表、可滚动内容区域的核心组件。
Scroll 的基本属性
-
scrollable:设置滚动方向
ScrollDirection.Vertical
(默认):垂直滚动ScrollDirection.Horizontal
:水平滚动ScrollDirection.None
:禁止滚动
-
scrollBar:设置滚动条显示策略
BarState.Auto
(默认):自动显示/隐藏BarState.On
:始终显示BarState.Off
:始终隐藏
-
edgeEffect:设置边缘效果
EdgeEffect.Spring
(默认):弹性效果EdgeEffect.Fade
:渐隐效果EdgeEffect.None
:无效果
-
onScroll:滚动事件回调
(xOffset: number, yOffset: number) => void
-
onScrollEdge:滚动到边缘事件回调
(side: Edge) => void
-
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%')}
}
性能优化建议
- 避免过度嵌套:尽量减少Scroll内部的嵌套层级
- 使用LazyForEach:对于超长列表,使用LazyForEach代替ForEach
- 分页加载:实现滚动到底部加载更多功能,避免一次性加载过多数据
- 图片优化:使用合适的图片尺寸和压缩格式
- 减少动态效果:在滚动区域减少复杂动画和频繁的状态更新
- 合理使用缓存:对于复杂子组件,考虑使用@Reusable装饰器
Scroll组件是构建可滚动界面的基础,合理使用可以创建流畅的用户体验。在复杂场景中,可以结合List、Grid等专用滚动组件获得更好的性能。