ts-container-scroll.md 14.5 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

## 接口

Scroll(scroller?: Scroller)

Y
yeyinglong 已提交
21 22 23 24 25 26
**参数:**

| 参数名 | 参数类型 | 必填 | 参数描述 |
| -------- | -------- | -------- | -------- |
| scroller | [Scroller](#scroller) | 否 | 可滚动组件的控制器。用于与可滚动组件进行绑定。 |

Z
zengyawen 已提交
27 28
## 属性

G
gmy 已提交
29 30 31 32
除支持[通用属性](ts-universal-attributes-size.md)外,还支持以下属性:

| 名称             | 参数类型                                     | 描述        |
| -------------- | ---------------------------------------- | --------- |
S
sienna1128 已提交
33
| scrollable     | [ScrollDirection](#scrolldirection枚举说明)                        | 设置滚动方向。<br/>默认值:ScrollDirection.Vertical |
Z
zhangrongjie 已提交
34
| scrollBar      | [BarState](ts-appendix-enums.md#barstate) | 设置滚动条状态。<br/>默认值:BarState.Auto<br/>**说明:** <br/>如果容器组件无法滚动,则滚动条不显示。如果容器组件的子组件大小为无穷大,则滚动条不支持拖动和伴随滚动。 |
S
sienna1128 已提交
35
| scrollBarColor | string&nbsp;\|&nbsp;number&nbsp;\|&nbsp;[Color](ts-appendix-enums.md#color)   | 设置滚动条的颜色。 |
Z
zhangrongjie 已提交
36
| scrollBarWidth | string&nbsp;\|&nbsp;number         | 设置滚动条的宽度,不支持百分比设置。<br/>默认值:4<br/>单位:vp<br/>**说明:** <br/>如果滚动条的宽度超过其高度,则滚动条的宽度会变为默认值。 |
W
wangshuainan 已提交
37
| edgeEffect     | [EdgeEffect](ts-appendix-enums.md#edgeeffect)            | 设置滑动效果,目前支持的滑动效果参见EdgeEffect的枚举说明。<br/>默认值:EdgeEffect.None |
Z
zengyawen 已提交
38

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

47 48
## 事件

G
gmy 已提交
49 50
| 名称                                                         | 功能描述                                                     |
| ------------------------------------------------------------ | ------------------------------------------------------------ |
Y
yamila 已提交
51 52
| onScrollFrameBegin<sup>9+</sup>(event: (offset: number, state: ScrollState) => { offsetRemain }) | 每帧开始滚动时触发,事件参数传入即将发生的滚动量,事件处理函数中可根据应用场景计算实际需要的滚动量并作为事件处理函数的返回值返回,Scroll将按照返回值的实际滚动量进行滚动。<br/>\- offset:即将发生的滚动量。<br/>\- state:当前滚动状态。<br/>- offsetRemain:实际滚动量。<br/>触发该事件的条件 :<br/>1、滚动组件触发滚动时触发,包括键鼠操作等其他触发滚动的输入设置。<br/>2、调用控制器接口时不触发。<br/>3、越界回弹不触发。<br/>**说明:** <br/>支持offsetRemain为负值。<br/>若通过onScrollFrameBegine事件和scrollBy方法实现容器嵌套滚动,需设置子滚动节点的EdgeEffect为None。如Scroll嵌套List滚动时,List组件的edgeEffect属性需设置为EdgeEffect.None。 |
| onScroll(event: (xOffset: number, yOffset: number) => void)  | 滚动事件回调,&nbsp;返回滚动时水平、竖直方向偏移量。<br/>触发该事件的条件 :<br/>1、滚动组件触发滚动时触发,支持键鼠操作等其他触发滚动的输入设置。<br/>2、通过滚动控制器API接口调用。<br/>3、越界回弹。 |
Z
zhangrongjie 已提交
53
| onScrollEdge(event: (side: Edge) => void)                    | 滚动到边缘事件回调。<br/>触发该事件的条件 :<br/>1、滚动组件滚动到边缘时触发,支持键鼠操作等其他触发滚动的输入设置。<br/>2、通过滚动控制器API接口调用。<br/>3、越界回弹。 |
Y
yamila 已提交
54
| onScrollEnd<sup>(deprecated) </sup>(event: () => void)       | 滚动停止事件回调。<br>该事件从API version 9开始废弃,使用onScrollStop事件替代。<br/>触发该事件的条件 :<br/>1、滚动组件触发滚动后停止,支持键鼠操作等其他触发滚动的输入设置。<br/>2、通过滚动控制器API接口调用后停止,带过渡动效。 |
Z
zhangrongjie 已提交
55
| onScrollStart<sup>9+</sup>(event: () => void)                | 滚动开始时触发。手指拖动Scroll或拖动Scroll的滚动条触发的滚动开始时,会触发该事件。使用[Scroller](#scroller)滚动控制器触发的带动画的滚动,动画开始时会触发该事件。<br/>触发该事件的条件 :<br/>1、滚动组件开始滚动时触发,支持键鼠操作等其他触发滚动的输入设置。<br/>2、通过滚动控制器API接口调用后开始,带过渡动效。 |
Y
yamila 已提交
56
| onScrollStop<sup>9+</sup>(event: () => void)                 | 滚动停止时触发。手拖动Scroll或拖动Scroll的滚动条触发的滚动,手离开屏幕并且滚动停止时会触发该事件。使用[Scroller](#scroller)滚动控制器触发的带动画的滚动,动画停止时会触发该事件。<br/>触发该事件的条件 :<br/>1、滚动组件触发滚动后停止,支持键鼠操作等其他触发滚动的输入设置。<br/>2、通过滚动控制器API接口调用后开始,带过渡动效,。 |
Z
zengyawen 已提交
57

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

Z
zengyawen 已提交
62
## Scroller
Z
zengyawen 已提交
63

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

Z
zengyawen 已提交
66 67

### 导入对象
Z
zengyawen 已提交
68 69 70 71 72 73

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


74
### scrollTo
Z
zengyawen 已提交
75 76 77

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

Z
zengyawen 已提交
78 79 80

滑动到指定位置。

G
gmy 已提交
81
**参数:**
Z
zengyawen 已提交
82

G
gmy 已提交
83 84
| 参数名    | 参数类型                                                     | 必填 | 参数描述                                                     |
| --------- | ------------------------------------------------------------ | ---- | ------------------------------------------------------------ |
Y
yamila 已提交
85 86 87
| xOffset   | number&nbsp;\|&nbsp;string                                   | 是   | 水平滑动偏移。<br/>**说明:** <br/>该参数值不支持设置百分比。<br/>仅滚动轴为x轴时生效。 |
| yOffset   | number&nbsp;\|&nbsp;string                                   | 是   | 垂直滑动偏移。<br/>**说明:** <br/>该参数值不支持设置百分比。<br/>仅滚动轴为y轴时生效。 |
| animation | {<br/>duration:&nbsp;number,<br/>curve:&nbsp;[Curve](ts-appendix-enums.md#curve)<br/>} | 否   | 动画配置:<br/>-&nbsp;duration:&nbsp;滚动时长设置。<br/>-&nbsp;curve:&nbsp;滚动曲线设置。<br/>默认值: <br/>{<br/>duration:&nbsp;0,<br/>curve:&nbsp;Curve.Ease<br/>}<br/>**说明:** <br/>设置为小于0的值时,按默认值显示。 |
Z
zengyawen 已提交
88 89


90
### scrollEdge
Z
zengyawen 已提交
91 92 93

scrollEdge(value: Edge): void

Z
zengyawen 已提交
94

Z
zhangrongjie 已提交
95
滚动到容器边缘,不区分滚动轴方向,Edge.Top和Edge.Start表现相同,Edge.Bottom和Edge.End表现相同。
Z
zengyawen 已提交
96

G
gmy 已提交
97
**参数:**
Z
zengyawen 已提交
98

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

Z
zengyawen 已提交
103

104
### scrollPage
Z
zengyawen 已提交
105 106

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

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

G
gmy 已提交
110 111 112 113 114
**参数:**

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


118
### currentOffset
Z
zengyawen 已提交
119

Y
yeyinglong 已提交
120
currentOffset(): { xOffset: number, yOffset: number }
Z
zengyawen 已提交
121

Z
zengyawen 已提交
122 123 124

返回当前的滚动偏移量。

G
gmy 已提交
125
**返回值**
Z
zengyawen 已提交
126

Y
yamila 已提交
127 128 129
| 类型                                                       | 描述                                                         |
| ---------------------------------------------------------- | ------------------------------------------------------------ |
| {<br/>xOffset:&nbsp;number,<br/>yOffset:&nbsp;number<br/>} | xOffset:&nbsp;水平滑动偏移;<br/>yOffset:&nbsp;竖直滑动偏移。<br/>**说明:** <br/>返回值单位为vp。 |
Z
zengyawen 已提交
130

Z
zengyawen 已提交
131

132
### scrollToIndex
Z
zengyawen 已提交
133

L
limeng 已提交
134
scrollToIndex(value: number, smooth?:boolean): void
Z
zengyawen 已提交
135 136 137

滑动到指定Index。

L
limeng 已提交
138 139
开启smooth动效时,会对经过的所有item进行加载和布局计算,当大量加载item时会导致性能问题。

Z
zengyawen 已提交
140

H
geshi  
HelloCrease 已提交
141
>  **说明:**
G
gmy 已提交
142
>
Z
zhangrongjie 已提交
143
>  仅支持Grid、List、WaterFlow组件。
Z
zengyawen 已提交
144

G
gmy 已提交
145
**参数:**
Z
zengyawen 已提交
146

L
limeng 已提交
147 148 149
| 参数名                | 参数类型 | 必填 | 参数描述                                                     |
| --------------------- | -------- | ---- | ------------------------------------------------------------ |
| value                 | number   | 是   | 要滑动到的列表项在列表中的索引值。                           |
150
| smooth<sup>10+ </sup> | boolean  | 否   | 设置滑动到列表项在列表中的索引值时是否有动效,true表示有动效,false表示没有动效。<br/>默认值:false。<br/>**说明:** <br/>当前仅List组件支持该参数。 |
Z
zengyawen 已提交
151

T
tianyu 已提交
152
### scrollBy<sup>9+</sup>
C
caocan 已提交
153 154 155 156 157 158 159 160

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


滑动指定距离。


>  **说明:**
G
gmy 已提交
161
>
Z
zhangrongjie 已提交
162
>  仅支持Scroll、ScrollBar、Grid、List组件。
C
caocan 已提交
163

G
gmy 已提交
164
**参数:**
C
caocan 已提交
165

G
gmy 已提交
166 167
| 参数名   | 参数类型   | 必填   | 参数描述              |
| ----- | ------ | ---- | ----------------- |
168 169
| dx | Length | 是    | 水平方向滚动距离,不支持百分比形式。 |
| dy | Length | 是    | 竖直方向滚动距离,不支持百分比形式。 |
C
caocan 已提交
170 171


Z
zengyawen 已提交
172
## 示例
S
sienna1128 已提交
173
### 示例1
Z
zengyawen 已提交
174

H
geshi  
HelloCrease 已提交
175 176
```ts
// xxx.ets
Z
zengyawen 已提交
177 178 179
@Entry
@Component
struct ScrollExample {
Y
yamila 已提交
180 181
  scroller: Scroller = new Scroller()
  private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Z
zengyawen 已提交
182 183 184 185 186 187 188

  build() {
    Stack({ alignContent: Alignment.TopStart }) {
      Scroll(this.scroller) {
        Column() {
          ForEach(this.arr, (item) => {
            Text(item.toString())
G
gmy 已提交
189 190 191 192 193 194
              .width('90%')
              .height(150)
              .backgroundColor(0xFFFFFF)
              .borderRadius(15)
              .fontSize(16)
              .textAlign(TextAlign.Center)
Z
zengyawen 已提交
195 196 197 198
              .margin({ top: 10 })
          }, item => item)
        }.width('100%')
      }
S
sienna1128 已提交
199 200 201
      .scrollable(ScrollDirection.Vertical)  // 滚动方向纵向
      .scrollBar(BarState.On)  // 滚动条常驻显示
      .scrollBarColor(Color.Gray)  // 滚动条颜色
Y
yamila 已提交
202
      .scrollBarWidth(10) // 滚动条宽度
S
sienna1128 已提交
203
      .edgeEffect(EdgeEffect.None)
Z
zengyawen 已提交
204
      .onScroll((xOffset: number, yOffset: number) => {
Y
yamila 已提交
205
        console.info(xOffset + ' ' + yOffset)
Z
zengyawen 已提交
206 207
      })
      .onScrollEdge((side: Edge) => {
Y
yamila 已提交
208
        console.info('To the edge')
Z
zengyawen 已提交
209 210
      })
      .onScrollEnd(() => {
Y
yamila 已提交
211
        console.info('Scroll Stop')
Z
zengyawen 已提交
212
      })
S
sienna1128 已提交
213

G
gmy 已提交
214
      Button('scroll 150')
Y
yamila 已提交
215
        .height('5%')
G
gmy 已提交
216
        .onClick(() => { // 点击后下滑指定距离150.0vp
Y
yamila 已提交
217
          this.scroller.scrollBy(0,150)
G
gmy 已提交
218 219
        })
        .margin({ top: 10, left: 20 })
Z
zengyawen 已提交
220
      Button('scroll 100')
Y
yamila 已提交
221
        .height('5%')
G
gmy 已提交
222
        .onClick(() => { // 点击后滑动到指定位置,即下滑100.0vp的距离
Y
yamila 已提交
223
          this.scroller.scrollTo({ xOffset: 0, yOffset: this.scroller.currentOffset().yOffset + 100 })
Z
zengyawen 已提交
224
        })
G
gmy 已提交
225
        .margin({ top: 60, left: 20 })
Z
zengyawen 已提交
226
      Button('back top')
Y
yamila 已提交
227
        .height('5%')
Z
zengyawen 已提交
228
        .onClick(() => { // 点击后回到顶部
Y
yamila 已提交
229
          this.scroller.scrollEdge(Edge.Top)
Z
zengyawen 已提交
230
        })
G
gmy 已提交
231
        .margin({ top: 110, left: 20 })
Z
zengyawen 已提交
232
      Button('next page')
Y
yamila 已提交
233
        .height('5%')
G
gmy 已提交
234
        .onClick(() => { // 点击后滑到下一页
Y
yamila 已提交
235
          this.scroller.scrollPage({ next: true })
Z
zengyawen 已提交
236
        })
G
gmy 已提交
237
        .margin({ top: 170, left: 20 })
Z
zengyawen 已提交
238 239 240 241 242
    }.width('100%').height('100%').backgroundColor(0xDCDCDC)
  }
}
```

Z
zengyawen 已提交
243
![zh-cn_image_0000001174104386](figures/zh-cn_image_0000001174104386.gif)
C
caocan 已提交
244

S
sienna1128 已提交
245
### 示例2
C
caocan 已提交
246 247 248 249
```ts
@Entry
@Component
struct NestedScroll {
S
sienna1128 已提交
250
  @State listPosition: number = 0; // 0代表滚动到List顶部,1代表中间值,2代表滚动到List底部。
Y
yamila 已提交
251
  private arr: number[] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Z
zhangrongjie 已提交
252 253
  private scrollerForScroll: Scroller = new Scroller()
  private scrollerForList: Scroller = new Scroller()
C
caocan 已提交
254 255 256

  build() {
    Flex() {
Z
zhangrongjie 已提交
257
      Scroll(this.scrollerForScroll) {
C
caocan 已提交
258 259 260 261
        Column() {
          Text("Scroll Area")
            .width("100%").height("40%").backgroundColor(0X330000FF)
            .fontSize(16).textAlign(TextAlign.Center)
Y
yamila 已提交
262
            .onClick(() => {
Z
zhangrongjie 已提交
263
              this.scrollerForList.scrollToIndex(5)
Y
yamila 已提交
264
            })
C
caocan 已提交
265

Z
zhangrongjie 已提交
266
          List({ space: 20, scroller: this.scrollerForList }) {
C
caocan 已提交
267 268 269 270 271 272 273 274
            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)
          }
Y
yamila 已提交
275 276 277
          .width("100%")
          .height("50%")
          .edgeEffect(EdgeEffect.None)
C
caocan 已提交
278
          .onReachStart(() => {
Y
yamila 已提交
279
            this.listPosition = 0
C
caocan 已提交
280 281
          })
          .onReachEnd(() => {
Y
yamila 已提交
282
            this.listPosition = 2
C
caocan 已提交
283
          })
Y
yeyinglong 已提交
284
          .onScrollFrameBegin((offset: number) => {
285 286
            if ((this.listPosition == 0 && offset <= 0) || (this.listPosition == 2 && offset >= 0)) {
              this.scrollerForScroll.scrollBy(0, offset)
Y
yeyinglong 已提交
287
              return { offsetRemain: 0 }
C
caocan 已提交
288
            }
Y
yamila 已提交
289
            this.listPosition = 1
Y
yeyinglong 已提交
290
            return { offsetRemain: offset };
C
caocan 已提交
291 292 293 294 295 296 297 298 299 300 301 302 303 304
          })

          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)