Scroll组件如何自动滚动到指定位置
===================

#### 问题现象

在Scroll组件中数据量较大时，滑动到指定页面效率较低，如何实现在进入Scroll列表后，能够自动滚动到指定位置？

#### 背景知识

[Scroll](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-container-scroll)是滚动的容器组件，当子组件的布局尺寸超过父组件的尺寸时，内容可以滚动。

*   [scrollTo](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-container-scroll#scrollto)：滑动到指定位置。
*   [scrollBy](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-container-scroll#scrollby9)：滑动指定距离。
*   [scrollToIndex](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-container-scroll#scrolltoindex)：滑动到指定Index，支持设置滑动额外偏移量。
*   [scrollToItemInGroup](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-container-list#scrolltoitemingroup11)：滑动到指定的ListItemGroup中指定的ListItem。

scrollTo、scrollBy和scrollToIndex可实现通用滚动控制，scrollToItemInGroup适用于多层级分组结构定位场景。

#### 解决方案

*   **场景一**：单层列表的快速定位。
    
    *   使用scrollTo，通过设置xOffset，yOffset的值来实现滑动到指定位置。
        
        _// scene1:使用scrollTo，通过设置xOffset，yOffset的值来实现滑动到指定位置。_
        sceneOne() {
          this.scroller.scrollTo({ xOffset: 700, yOffset: 700 });
        }
        
    *   使用scrollBy，设置dx，dy滑动指定距离。
        
        _// scene2:使用scrollBy，设置dx，dy滑动指定距离。_
        sceneTwo() {
          this.scroller.scrollBy(700, 700); _// dx=700,dy=700_
        }
        
    *   使用scrollToIndex，通过设置其中的参数value，options来实现滑动到指定位置的效果。
        
        _// scene3:使用scrollToIndex，通过设置其中的参数value，options来实现。_
        sceneThree() {
          this.scroller.scrollToIndex(1, false, ScrollAlign.START, {
            extraOffset: { value: 80, unit: 0 } _// 设置额外偏移量_
          });
        }
        
    
    使用scrollTo完整示例参考如下：
    
    @Entry
    @Component
    struct ListExample {
      private arr: number\[\] = \[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15\];
      private scroller: Scroller = new Scroller();
    
     _ // scene1:使用scrollTo，通过设置xOffset，yOffset的值来实现滑动到指定位置。_
      sceneOne() {
        this.scroller.scrollTo({ xOffset: 700, yOffset: 700 });
      }
    
      _// scene2:使用scrollBy，设置dx，dy滑动指定距离。_
      sceneTwo() {
        this.scroller.scrollBy(700, 700); _// dx=700,dy=700_
      }
    
     _ // scene3:使用scrollToIndex，通过设置其中的参数value，options来实现。_
      sceneThree() {
        this.scroller.scrollToIndex(1, false, ScrollAlign.START, {
          extraOffset: { value: 80, unit: 0 } _// 设置额外偏移量_
        });
      }
    
      build() {
        Column() {
          Button('跳转到指定位置')
            .margin({ bottom: 16 })
            .onClick(() => {
              this.sceneOne();
            });
          List({ space: 20, initialIndex: 0, scroller: this.scroller }) {
            ForEach(this.arr, (item: number) => {
              ListItem() {
                Text('' + item)
                  .width('100%')
                  .height(100)
                  .fontSize(16)
                  .textAlign(TextAlign.Center)
                  .borderRadius(10)
                  .backgroundColor(0xFFFFFF);
              }
              .borderRadius(10)
              .backgroundColor('#fff');
            }, (item: string) => item);
          }
          .listDirection(Axis.Vertical)
          .scrollBar(BarState.Off)
          .friction(0.6)
          .divider({
            strokeWidth: 2,
            color: '#33ffffff',
            startMargin: 20,
            endMargin: 20,
          })
          .edgeEffect(EdgeEffect.Spring)
          .width('100%');
        }
        .expandSafeArea(\[SafeAreaType.SYSTEM\], \[SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM\])
        .width('100%')
        .height('100%')
        .backgroundColor('#f1f3f5')
        .padding(16);
      }
    }
    
    效果预览：
    
    ![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/ea/v3/7Kslhxg7RKOxzjWntOQ1xQ/zh-cn_image_0000002658911917.png?HW-CC-KV=V1&HW-CC-Date=20260709T133907Z&HW-CC-Expire=86400&HW-CC-Sign=00F78FEC0B16312B19FE8AD6AAFE4584CC70A60C69A86943474FFEF06DB44434 "点击放大")
    
*   **场景二**：多层级分组结构，精准跳转至某个特定的分组中的某一项。
    
    使用scrollToItemInGroup定位到分组列表中指定分组内的目标项。
    
    @Entry
    @Component
    struct ListItemGroupExample {
      listScroller: ListScroller = new ListScroller();
      _//列表数据_
      private timeTable: TimeTable\[\] = \[
        {
          title: '星期一',
          projects: \['语文', '数学', '英语', '物理'\]
        },
        {
          title: '星期二',
          projects: \['物理', '化学', '生物', '数学'\]
        },
        {
          title: '星期三',
          projects: \['历史', '地理', '政治', '数学'\]
        },
        {
          title: '星期四',
          projects: \['美术', '音乐', '体育', '数学'\]
        },
        {
          title: '星期五',
          projects: \['美术', '音乐', '体育', '数学'\]
        }
      \];
    
      @Builder
      itemHead(text: string) {
        Column() {
          Text(text)
            .fontSize(20)
            .borderRadius(8)
            .padding(10);
        }
        .justifyContent(FlexAlign.Center)
        .alignItems(HorizontalAlign.Start)
        .backgroundColor('#f1f3f5')
        .width('100%')
        .height(50);
      }
    
      @Builder
      itemFoot(num: number) {
        Text('共' + num + '节课')
          .fontSize(16)
          .width('90%')
          .borderRadius(8)
          .padding(5);
      }
    
      build() {
        Column({ space: 20 }) {
          List({ space: 16, scroller: this.listScroller }) {
            ForEach(this.timeTable, (item: TimeTable) => {
              ListItemGroup({ header: this.itemHead(item.title), footer: this.itemFoot(item.projects.length) }) {
                ForEach(item.projects, (project: string) => {
                  ListItem() {
                    Text(project)
                      .width('90%')
                      .height(100)
                      .fontSize(20)
                      .textAlign(TextAlign.Center);
    
                  }
                  .backgroundColor('#fff')
                  .borderRadius(16)
                  .margin({ top: 8, bottom: 8 });
                }, (item: string) => item);
              };
            });
          }
          .alignListItem(ListItemAlign.Center)
          .width('100%')
          .height(655)
          .sticky(StickyStyle.Header)
          .scrollBar(BarState.Off);
    
          Button('scrollToItemInGroup')
            .margin({
              bottom: 16
            })
            .onClick(() => {
              try {
           _     //使用scrollToItemInGroup定位到分组列表中指定分组内的目标项_
                this.listScroller.scrollToItemInGroup(2, 1);
              } catch (error) {
                console.error(\`error: ${error}\`);
              }
            });
        }
        .justifyContent(FlexAlign.SpaceBetween)
        .expandSafeArea(\[SafeAreaType.SYSTEM\], \[SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM\])
        .width('100%')
        .height('100%')
        .backgroundColor('#f1f3f5')
        .padding({ top: 5 });
      }
    }
    
    interface TimeTable {
      title: string;
      projects: string\[\];
    }
    
    效果预览：
    
    ![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/6c/v3/6pbb4W2BTAqjQLwRo5ikfA/zh-cn_image_0000002628392708.png?HW-CC-KV=V1&HW-CC-Date=20260709T133907Z&HW-CC-Expire=86400&HW-CC-Sign=7A9E47569FF6BE5ABF6AA1B353DF1B63849182159558488E3D4838721CFBB245 "点击放大")
    

#### 总结

| 
方法名称

 | 

适用场景

 | 

核心特点

 |
| :-- | :-- | :-- |
| 

scrollTo

 | 

精准定位（如跳转到固定坐标、锚点、特定区域）。

 | 

直接指定像素坐标，无需计算索引，适合固定位置的快速跳转（如跳转到顶部、底部或某个模块）。

 |
| 

scrollBy

 | 

动态调整（如手势滑动后的微调、自动滚动补偿）。

 | 

基于当前滚动位置的增量滑动，适配用户交互行为，常用于实时响应用户操作（如拖动后继续滑动）。

 |
| 

scrollToIndex

 | 

单层列表快速定位（如跳转到列表中的某一项）。

 | 

通过索引直接定位，支持额外偏移量（如居中显示某一项），简化索引计算，适合列表数据密集的场景。

 |
| 

scrollToItemInGroup

 | 

多层级分组结构精准跳转。

 | 

直接定位到分组内的具体子项（多级分类导航、分组列表的快速跳转）。

 |