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

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

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

Z
zengyawen 已提交
10

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

支持单个子组件。

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

## 接口

Scroll(scroller?: Scroller)

## 属性

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

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

K
kangchongtao 已提交
32
## ScrollDirection枚举说明
G
gmy 已提交
33 34 35 36 37 38
| 名称       | 描述                     |
| ---------- | ------------------------ |
| Horizontal | 仅支持水平方向滚动。     |
| Vertical   | 仅支持竖直方向滚动。     |
| None       | 不可滚动。               |
| Free       | 支持竖直或水平方向滚动。 |
Z
zengyawen 已提交
39

K
kangchongtao 已提交
40 41 42 43 44 45 46 47
## EdgeEffect枚举说明

| 名称     | 描述                                       |
| ------ | ---------------------------------------- |
| Spring | 弹性物理动效,滑动到边缘后可以根据初始速度或通过触摸事件继续滑动一段距离,松手后回弹。 |
| Fade   | 阴影效果,滑动到边缘后会有圆弧状的阴影。          |
| None   | 滑动到边缘后无效果。                               |

48 49
## 事件

G
gmy 已提交
50 51 52 53 54 55
| 名称                                                         | 功能描述                                                     |
| ------------------------------------------------------------ | ------------------------------------------------------------ |
| 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 已提交
56

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

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

K
kangchongtao 已提交
63
可滚动容器组件的控制器,可以将此组件绑定至容器组件,然后通过它控制容器组件的滚动,目前支持绑定到List、Scroll、ScrollBar上。
Z
zengyawen 已提交
64

Z
zengyawen 已提交
65 66

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

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


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

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

Z
zengyawen 已提交
77 78 79

滑动到指定位置。

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

G
gmy 已提交
82 83 84 85 86
| 参数名    | 参数类型                                                     | 必填 | 参数描述                                                     |
| --------- | ------------------------------------------------------------ | ---- | ------------------------------------------------------------ |
| xOffset   | Length                                                       | 是   | 水平滑动偏移。                                               |
| yOffset   | Length                                                       | 是   | 竖直滑动偏移。                                               |
| animation | {<br/>duration:&nbsp;number,<br/>curve:&nbsp;[Curve](ts-animatorproperty.md)&nbsp;\|<br/>CubicBezier&nbsp;\|<br/>SpringCurve<br/>} | 否   | 动画配置:<br/>-&nbsp;duration:&nbsp;滚动时长设置。<br/>-&nbsp;curve:&nbsp;滚动曲线设置。 |
Z
zengyawen 已提交
87 88


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

scrollEdge(value: Edge): void

Z
zengyawen 已提交
93 94 95

滚动到容器边缘。

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

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

Z
zengyawen 已提交
102

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

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

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

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

| 参数名       | 参数类型    | 必填   | 参数描述                           |
| --------- | ------- | ---- | ------------------------------ |
| next      | boolean | 是    | 是否向下翻页。true表示向下翻页,false表示向上翻页。 |
| direction | [Axis](ts-appendix-enums.md#axis)    | 否    | 设置滚动方向为水平或竖直方向。                |
Z
zengyawen 已提交
115 116


117
### currentOffset
Z
zengyawen 已提交
118

G
gmy 已提交
119
currentOffset()
Z
zengyawen 已提交
120

Z
zengyawen 已提交
121 122 123

返回当前的滚动偏移量。

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

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

Z
zengyawen 已提交
130

131
### scrollToIndex
Z
zengyawen 已提交
132

C
caocan 已提交
133
scrollToIndex(value: number): void
Z
zengyawen 已提交
134 135 136 137


滑动到指定Index。

Z
zengyawen 已提交
138

H
geshi  
HelloCrease 已提交
139
>  **说明:**
G
gmy 已提交
140 141
>
>  仅支持list组件。
Z
zengyawen 已提交
142

G
gmy 已提交
143
**参数:**
Z
zengyawen 已提交
144

G
gmy 已提交
145 146 147
| 参数名 | 参数类型 | 必填 | 参数描述                           |
| ------ | -------- | ---- | ---------------------------------- |
| value  | number   | 是   | 要滑动到的列表项在列表中的索引值。 |
Z
zengyawen 已提交
148 149


C
caocan 已提交
150 151 152 153 154 155 156 157 158
### scrollBy

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


滑动指定距离。


>  **说明:**
G
gmy 已提交
159 160
>
>  仅支持Scroll组件。
C
caocan 已提交
161

G
gmy 已提交
162
**参数:**
C
caocan 已提交
163

G
gmy 已提交
164 165 166 167
| 参数名   | 参数类型   | 必填   | 参数描述              |
| ----- | ------ | ---- | ----------------- |
| dx | Length | 是    | 水平方向滚动距离。 |
| dy | Length | 是    | 竖直方向滚动距离。 |
C
caocan 已提交
168 169


Z
zengyawen 已提交
170
## 示例
Z
zengyawen 已提交
171

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

Z
zengyawen 已提交
235
![zh-cn_image_0000001174104386](figures/zh-cn_image_0000001174104386.gif)
C
caocan 已提交
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 284 285 286 287 288 289 290


```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)