ts-container-scroll.md 10.2 KB
Newer Older
Z
zengyawen 已提交
1 2
# Scroll

G
gmy 已提交
3 4
可滚动的容器组件,当子组件的布局尺寸超过父组件的尺寸时,内容可以滚动。

H
geshi  
HelloCrease 已提交
5
>  **说明:**
G
gmy 已提交
6 7
>  - 该组件从API version 7开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。
>  - 该组件嵌套List子组件滚动时,若List不设置宽高,则默认全部加载,在对性能有要求的场景下建议指定List的宽高。
8
>  - 该组件滚动的前提是主轴方向大小小于内容大小。
G
gmy 已提交
9
>  - 该组件回弹的前提是要有滚动。内容小于一屏时,没有回弹效果。
Z
zengyawen 已提交
10

Z
zengyawen 已提交
11

Z
zengyawen 已提交
12
## 子组件
Z
zengyawen 已提交
13 14 15

支持单个子组件。

Z
zengyawen 已提交
16 17 18 19 20 21 22

## 接口

Scroll(scroller?: Scroller)

## 属性

G
gmy 已提交
23 24 25 26
除支持[通用属性](ts-universal-attributes-size.md)外,还支持以下属性:

| 名称             | 参数类型                                     | 描述        |
| -------------- | ---------------------------------------- | --------- |
T
tianyu 已提交
27
| scrollable     | ScrollDirection                          | 设置滚动方向。<br/>默认值:ScrollDirection.Vertical |
G
gmy 已提交
28 29 30
| scrollBar      | [BarState](ts-appendix-enums.md#barstate) | 设置滚动条状态。<br/>默认值:BarState.Off |
| scrollBarColor | string&nbsp;\|&nbsp;number&nbsp;\|&nbsp;Color   | 设置滚动条的颜色。 |
| scrollBarWidth | string&nbsp;\|&nbsp;number         | 设置滚动条的宽度。 |
31
| edgeEffect     | [EdgeEffect](ts-appendix-enums.md#edgeeffect)            | 设置滑动效果,目前支持的滑动效果参见EdgeEffect的枚举说明。<br/>默认值:EdgeEffect.Spring |
Z
zengyawen 已提交
32

K
kangchongtao 已提交
33
## ScrollDirection枚举说明
G
gmy 已提交
34 35 36 37 38
| 名称       | 描述                     |
| ---------- | ------------------------ |
| Horizontal | 仅支持水平方向滚动。     |
| Vertical   | 仅支持竖直方向滚动。     |
| None       | 不可滚动。               |
39
| Free<sup>(deprecated) </sup> | 支持竖直或水平方向滚动<br/> 从API version 9开始废弃|
K
kangchongtao 已提交
40

41 42
## 事件

G
gmy 已提交
43 44 45 46 47 48
| 名称                                                         | 功能描述                                                     |
| ------------------------------------------------------------ | ------------------------------------------------------------ |
| onScrollBegin<sup>9+</sup>(event: (dx: number, dy: number) => { dxRemain: number, dyRemain: number }) | 滚动开始事件回调。<br>参数:<br>- dx:即将发生的水平方向滚动量。<br>- dy:即将发生的竖直方向滚动量。<br>返回值:<br>- dxRemain:水平方向滚动剩余量。<br>- dyRemain:竖直方向滚动剩余量。 |
| onScroll(event: (xOffset: number, yOffset: number) => void)  | 滚动事件回调,&nbsp;返回滚动时水平、竖直方向偏移量。          |
| onScrollEdge(event: (side: Edge) => void)                    | 滚动到边缘事件回调。                                         |
| onScrollEnd(event: () => void)                               | 滚动停止事件回调。                                           |
Z
zengyawen 已提交
49

C
caocan 已提交
50
>  **说明:**
G
gmy 已提交
51 52
>
>  若通过onScrollBegin事件和scrollBy方法实现容器嵌套滚动,需设置子滚动节点的EdgeEffect为None。如Scroll嵌套List滚动时,List组件的edgeEffect属性需设置为EdgeEffect.None。
C
caocan 已提交
53

Z
zengyawen 已提交
54
## Scroller
Z
zengyawen 已提交
55

L
lijuan124 已提交
56
可滚动容器组件的控制器,可以将此组件绑定至容器组件,然后通过它控制容器组件的滚动,同一个控制器不可以控制多个容器组件,目前支持绑定到List、Scroll、ScrollBar上。
Z
zengyawen 已提交
57

Z
zengyawen 已提交
58 59

### 导入对象
Z
zengyawen 已提交
60 61 62 63 64 65

```
scroller: Scroller = new Scroller()
```


66
### scrollTo
Z
zengyawen 已提交
67 68 69

scrollTo(value: { xOffset: number | string, yOffset: number | string, animation?: { duration: number, curve: Curve } }): void

Z
zengyawen 已提交
70 71 72

滑动到指定位置。

G
gmy 已提交
73
**参数:**
Z
zengyawen 已提交
74

G
gmy 已提交
75 76 77 78
| 参数名    | 参数类型                                                     | 必填 | 参数描述                                                     |
| --------- | ------------------------------------------------------------ | ---- | ------------------------------------------------------------ |
| xOffset   | Length                                                       | 是   | 水平滑动偏移。                                               |
| yOffset   | Length                                                       | 是   | 竖直滑动偏移。                                               |
79
| animation | {<br/>duration:&nbsp;number,<br/>curve:&nbsp;[Curve](ts-animatorproperty.md)<br/>} | 否   | 动画配置:<br/>-&nbsp;duration:&nbsp;滚动时长设置。<br/>-&nbsp;curve:&nbsp;滚动曲线设置。 |
Z
zengyawen 已提交
80 81


82
### scrollEdge
Z
zengyawen 已提交
83 84 85

scrollEdge(value: Edge): void

Z
zengyawen 已提交
86 87 88

滚动到容器边缘。

G
gmy 已提交
89
**参数:**
Z
zengyawen 已提交
90

G
gmy 已提交
91 92 93
| 参数名   | 参数类型 | 必填   | 参数描述      |
| ----- | ---- | ---- | --------- |
| value | [Edge](ts-appendix-enums.md#edge) | 是    | 滚动到的边缘位置。 |
G
gmy 已提交
94

Z
zengyawen 已提交
95

96
### scrollPage
Z
zengyawen 已提交
97 98

scrollPage(value: { next: boolean, direction?: Axis }): void
Z
zengyawen 已提交
99 100

滚动到下一页或者上一页。
Z
zengyawen 已提交
101

G
gmy 已提交
102 103 104 105 106
**参数:**

| 参数名       | 参数类型    | 必填   | 参数描述                           |
| --------- | ------- | ---- | ------------------------------ |
| next      | boolean | 是    | 是否向下翻页。true表示向下翻页,false表示向上翻页。 |
107
| direction<sup>(deprecated) </sup> | [Axis](ts-appendix-enums.md#axis)    | 否    | 设置滚动方向为水平或竖直方向。<br/> 从API version 9开始废弃                |
Z
zengyawen 已提交
108 109


110
### currentOffset
Z
zengyawen 已提交
111

G
gmy 已提交
112
currentOffset()
Z
zengyawen 已提交
113

Z
zengyawen 已提交
114 115 116

返回当前的滚动偏移量。

G
gmy 已提交
117
**返回值**
Z
zengyawen 已提交
118

G
gmy 已提交
119 120 121
| 类型                                       | 描述                                       |
| ---------------------------------------- | ---------------------------------------- |
| {<br/>xOffset:&nbsp;number,<br/>yOffset:&nbsp;number<br/>} | xOffset:&nbsp;水平滑动偏移;<br/>yOffset:&nbsp;竖直滑动偏移。 |
Z
zengyawen 已提交
122

Z
zengyawen 已提交
123

124
### scrollToIndex
Z
zengyawen 已提交
125

C
caocan 已提交
126
scrollToIndex(value: number): void
Z
zengyawen 已提交
127 128 129 130


滑动到指定Index。

Z
zengyawen 已提交
131

H
geshi  
HelloCrease 已提交
132
>  **说明:**
G
gmy 已提交
133 134
>
>  仅支持list组件。
Z
zengyawen 已提交
135

G
gmy 已提交
136
**参数:**
Z
zengyawen 已提交
137

G
gmy 已提交
138 139 140
| 参数名 | 参数类型 | 必填 | 参数描述                           |
| ------ | -------- | ---- | ---------------------------------- |
| value  | number   | 是   | 要滑动到的列表项在列表中的索引值。 |
Z
zengyawen 已提交
141 142


T
tianyu 已提交
143
### scrollBy<sup>9+</sup>
C
caocan 已提交
144 145 146 147 148 149 150 151

scrollBy(dx: Length, dy: Length): void


滑动指定距离。


>  **说明:**
G
gmy 已提交
152 153
>
>  仅支持Scroll组件。
C
caocan 已提交
154

G
gmy 已提交
155
**参数:**
C
caocan 已提交
156

G
gmy 已提交
157 158
| 参数名   | 参数类型   | 必填   | 参数描述              |
| ----- | ------ | ---- | ----------------- |
159 160
| dx | Length | 是    | 水平方向滚动距离,不支持百分比形式。 |
| dy | Length | 是    | 竖直方向滚动距离,不支持百分比形式。 |
C
caocan 已提交
161 162


Z
zengyawen 已提交
163
## 示例
Z
zengyawen 已提交
164

H
geshi  
HelloCrease 已提交
165 166
```ts
// xxx.ets
Z
zengyawen 已提交
167 168 169 170 171 172 173 174 175 176 177 178
@Entry
@Component
struct ScrollExample {
  scroller: Scroller = new Scroller()
  private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

  build() {
    Stack({ alignContent: Alignment.TopStart }) {
      Scroll(this.scroller) {
        Column() {
          ForEach(this.arr, (item) => {
            Text(item.toString())
G
gmy 已提交
179 180 181 182 183 184
              .width('90%')
              .height(150)
              .backgroundColor(0xFFFFFF)
              .borderRadius(15)
              .fontSize(16)
              .textAlign(TextAlign.Center)
Z
zengyawen 已提交
185 186 187 188
              .margin({ top: 10 })
          }, item => item)
        }.width('100%')
      }
G
gmy 已提交
189 190 191 192
      .scrollable(ScrollDirection.Vertical)
      .scrollBar(BarState.On)
      .scrollBarColor(Color.Gray)
      .scrollBarWidth(30)
Z
zengyawen 已提交
193 194 195 196 197 198 199 200 201
      .onScroll((xOffset: number, yOffset: number) => {
        console.info(xOffset + ' ' + yOffset)
      })
      .onScrollEdge((side: Edge) => {
        console.info('To the edge')
      })
      .onScrollEnd(() => {
        console.info('Scroll Stop')
      })
202
      
G
gmy 已提交
203 204 205 206 207
      Button('scroll 150')
        .onClick(() => { // 点击后下滑指定距离150.0vp
          this.scroller.scrollBy(0,150)
        })
        .margin({ top: 10, left: 20 })
Z
zengyawen 已提交
208
      Button('scroll 100')
G
gmy 已提交
209
        .onClick(() => { // 点击后滑动到指定位置,即下滑100.0vp的距离
Z
zengyawen 已提交
210 211
          this.scroller.scrollTo({ xOffset: 0, yOffset: this.scroller.currentOffset().yOffset + 100 })
        })
G
gmy 已提交
212
        .margin({ top: 60, left: 20 })
Z
zengyawen 已提交
213 214 215 216
      Button('back top')
        .onClick(() => { // 点击后回到顶部
          this.scroller.scrollEdge(Edge.Top)
        })
G
gmy 已提交
217
        .margin({ top: 110, left: 20 })
Z
zengyawen 已提交
218
      Button('next page')
G
gmy 已提交
219
        .onClick(() => { // 点击后滑到下一页
Z
zengyawen 已提交
220 221
          this.scroller.scrollPage({ next: true })
        })
G
gmy 已提交
222
        .margin({ top: 170, left: 20 })
Z
zengyawen 已提交
223 224 225 226 227
    }.width('100%').height('100%').backgroundColor(0xDCDCDC)
  }
}
```

Z
zengyawen 已提交
228
![zh-cn_image_0000001174104386](figures/zh-cn_image_0000001174104386.gif)
C
caocan 已提交
229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283


```ts
@Entry
@Component
struct NestedScroll {
  @State listPosition: number = 0 // 0代表滚动到List顶部,1代表中间值,2代表滚动到List底部。
  private arr: number[] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
  private scroller: Scroller = new Scroller()

  build() {
    Flex() {
      Scroll(this.scroller) {
        Column() {
          Text("Scroll Area")
            .width("100%").height("40%").backgroundColor(0X330000FF)
            .fontSize(16).textAlign(TextAlign.Center)

          List({ space: 20 }) {
            ForEach(this.arr, (item) => {
              ListItem() {
                Text("ListItem" + item)
                  .width("100%").height("100%").borderRadius(15)
                  .fontSize(16).textAlign(TextAlign.Center).backgroundColor(Color.White)
              }.width("100%").height(100)
            }, item => item)
          }
          .width("100%").height("50%").edgeEffect(EdgeEffect.None)
          .onReachStart(() => {
            this.listPosition = 0
          })
          .onReachEnd(() => {
            this.listPosition = 2
          })
          .onScrollBegin((dx: number, dy: number) => {
            if ((this.listPosition == 0 && dy >= 0) || (this.listPosition == 2 && dy <= 0)) {
              this.scroller.scrollBy(0, -dy)
              return { dxRemain: dx, dyRemain: 0 }
            }
            this.listPosition = 1;
            return { dxRemain: dx, dyRemain: dy }
          })

          Text("Scroll Area")
            .width("100%").height("40%").backgroundColor(0X330000FF)
            .fontSize(16).textAlign(TextAlign.Center)
        }
      }
      .width("100%").height("100%")
    }.width('100%').height('100%').backgroundColor(0xDCDCDC).padding(20)
  }
}
```

![NestedScroll](figures/NestedScroll.gif)