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

E
ester.zhou 已提交
3 4
The **\<Scroll>** component scrolls the content when the layout size of a component exceeds the size of its parent component.

E
ester.zhou 已提交
5
>  **NOTE**
E
esterzhou 已提交
6 7
>  - This component is supported since API version 7. Updates will be marked with a superscript to indicate their earliest API version.
>  - When nesting a **\<List>** within this component, specify the width and height for the **\<List>** under scenarios where consistently high performance is required. If the width and height are not specified, this component will load all content of the **\<List>**.
E
ester.zhou 已提交
8
>  - This component can scroll only when the size on the main axis is less than the content size.
E
ester.zhou 已提交
9
>  - This component can produce a bounce effect only when there is more than one screen of content.
Z
zengyawen 已提交
10

Z
zengyawen 已提交
11 12

## Child Components
Z
zengyawen 已提交
13 14 15

This component supports only one child component.

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

## APIs

Scroll(scroller?: Scroller)

## Attributes

E
ester.zhou 已提交
23
In addition to the [universal attributes](ts-universal-attributes-size.md), the following attributes are supported.
Z
zengyawen 已提交
24

E
ester.zhou 已提交
25 26
| Name            | Type                                    | Description       |
| -------------- | ---------------------------------------- | --------- |
E
ester.zhou 已提交
27
| scrollable     | [ScrollDirection](#scrolldirection)                        | Scroll direction.<br>Default value: **ScrollDirection.Vertical**|
E
ester.zhou 已提交
28
| scrollBar      | [BarState](ts-appendix-enums.md#barstate) | Scrollbar status.<br>Default value: **BarState.Auto**|
E
ester.zhou 已提交
29
| scrollBarColor | string \| number \| [Color](ts-appendix-enums.md#color)   | Color of the scrollbar.|
E
ester.zhou 已提交
30
| scrollBarWidth | string \| number         | Width of the scrollbar.|
E
ester.zhou 已提交
31
| edgeEffect     | [EdgeEffect](ts-appendix-enums.md#edgeeffect)            | Scroll effect. For details, see **EdgeEffect**.<br>Default value: **EdgeEffect.None**|
Z
zengyawen 已提交
32

E
ester.zhou 已提交
33 34 35 36 37 38
## ScrollDirection
| Name      | Description                    |
| ---------- | ------------------------ |
| Horizontal | Only horizontal scrolling is supported.    |
| Vertical   | Only vertical scrolling is supported.    |
| None       | Scrolling is disabled.              |
E
ester.zhou 已提交
39
| Free<sup>(deprecated) </sup> | Vertical or horizontal scrolling is supported.<br> This API is deprecated since API version 9.|
E
esterzhou 已提交
40

41 42
## Events

E
ester.zhou 已提交
43 44 45 46 47 48
| Name                                                        | Description                                                    |
| ------------------------------------------------------------ | ------------------------------------------------------------ |
| onScrollBegin<sup>9+</sup>(event: (dx: number, dy: number) => { dxRemain: number, dyRemain: number }) | Invoked when scrolling starts.<br>Parameters:<br>- **dx**: amount to scroll by in the horizontal direction.<br>- **dy**: amount to scroll by in the vertical direction.<br>Return value:<br>- **dxRemain**: remaining amount to scroll by in the horizontal direction.<br>- **dyRemain**: remaining amount to scroll by in the vertical direction.|
| onScroll(event: (xOffset: number, yOffset: number) => void)  | Invoked to return the horizontal and vertical offsets during scrolling when the specified scroll event occurs.         |
| onScrollEdge(event: (side: Edge) => void)                    | Invoked when scrolling reaches the edge.                                        |
| onScrollEnd(event: () => void)                               | Invoked when scrolling stops.                                          |
49 50

>  **NOTE**
E
ester.zhou 已提交
51 52
>
>  If the **onScrollBegin** event and **scrollBy** API are used to implement nested scrolling, you must set **edgeEffect** of the scrolling child node to **None**. For example, if a **\<List>** is nested in the **\<Scroll>** component, the **edgeEffect** attribute of the **\<List>** must be set to **EdgeEffect.None**.
Z
zengyawen 已提交
53 54 55

## Scroller

E
ester.zhou 已提交
56
Implements a controller for a scrollable container component. You can bind this component to a container component and use it to control the scrolling of that component. Currently, this controller can be bound to the **\<List>**, **\<Scroll>** and **\<ScrollBar>** components. One controller can control only one container component.
Z
zengyawen 已提交
57 58 59 60


### Objects to Import

Z
zengyawen 已提交
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

Scrolls to the specified position.

E
ester.zhou 已提交
73
**Parameters**
Z
zengyawen 已提交
74

E
ester.zhou 已提交
75 76 77 78 79
| Name   | Type                                                    | Mandatory| Description                                                    |
| --------- | ------------------------------------------------------------ | ---- | ------------------------------------------------------------ |
| xOffset   | Length                                                       | Yes  | Horizontal scrolling offset.                                              |
| yOffset   | Length                                                       | Yes  | Vertical scrolling offset.                                              |
| animation | {<br>duration: number,<br>curve: [Curve](ts-animatorproperty.md)<br>} | No  | Animation configuration, which includes the following:<br>- **duration**: scrolling duration.<br>- **curve**: scrolling curve.|
Z
zengyawen 已提交
80 81


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

scrollEdge(value: Edge): void

Z
zengyawen 已提交
86 87 88

Scrolls to the edge of the container.

E
ester.zhou 已提交
89
**Parameters**
Z
zengyawen 已提交
90

E
ester.zhou 已提交
91 92 93
| Name  | Type| Mandatory  | Description     |
| ----- | ---- | ---- | --------- |
| value | [Edge](ts-appendix-enums.md#edge) | Yes   | Edge position to scroll to.|
E
ester.zhou 已提交
94

Z
zengyawen 已提交
95

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

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

Scrolls to the next or previous page.
Z
zengyawen 已提交
101

E
ester.zhou 已提交
102 103 104 105 106
**Parameters**

| Name      | Type   | Mandatory  | Description                          |
| --------- | ------- | ---- | ------------------------------ |
| next      | boolean | Yes   | Whether to turn to the next page. The value **true** means to scroll to the next page, and **false** means to scroll to the previous page.|
E
ester.zhou 已提交
107
| direction<sup>(deprecated) </sup> | [Axis](ts-appendix-enums.md#axis)    | No   | Scrolling direction: horizontal or vertical.<br> This API is deprecated since API version 9.               |
Z
zengyawen 已提交
108 109


110
### currentOffset
Z
zengyawen 已提交
111

E
ester.zhou 已提交
112
currentOffset()
Z
zengyawen 已提交
113

Z
zengyawen 已提交
114 115 116

Obtains the scrolling offset.

E
ester.zhou 已提交
117
**Return value**
Z
zengyawen 已提交
118

E
ester.zhou 已提交
119 120 121
| Type                                      | Description                                      |
| ---------------------------------------- | ---------------------------------------- |
| {<br>xOffset: number,<br>yOffset: number<br>} | **xOffset**: horizontal scrolling offset.<br>**yOffset**: vertical scrolling offset.|
Z
zengyawen 已提交
122

Z
zengyawen 已提交
123

E
ester.zhou 已提交
124
### scrollToIndex
Z
zengyawen 已提交
125

E
ester.zhou 已提交
126
scrollToIndex(value: number): void
Z
zengyawen 已提交
127 128


E
ester.zhou 已提交
129
Scrolls to the item with the specified index.
Z
zengyawen 已提交
130

Z
zengyawen 已提交
131

E
ester.zhou 已提交
132
>  **NOTE**
E
ester.zhou 已提交
133 134
>
>  Only the **\<List>** component is supported.
Z
zengyawen 已提交
135

E
ester.zhou 已提交
136
**Parameters**
Z
zengyawen 已提交
137

E
ester.zhou 已提交
138 139 140
| Name| Type| Mandatory| Description                          |
| ------ | -------- | ---- | ---------------------------------- |
| value  | number   | Yes  | Index of the item to be scrolled to in the list.|
Z
zengyawen 已提交
141 142


E
ester.zhou 已提交
143
### scrollBy<sup>9+</sup>
Z
zengyawen 已提交
144

145
scrollBy(dx: Length, dy: Length): void
Z
zengyawen 已提交
146 147


148
Scrolls by the specified amount.
Z
zengyawen 已提交
149

Z
zengyawen 已提交
150

151
>  **NOTE**
E
ester.zhou 已提交
152 153
>
>  Only the **\<Scroll>** component is supported.
154

E
ester.zhou 已提交
155
**Parameters**
156

E
ester.zhou 已提交
157 158 159 160
| Name  | Type  | Mandatory  | Description             |
| ----- | ------ | ---- | ----------------- |
| dx | Length | Yes   | Amount to scroll by in the horizontal direction. The percentage format is not supported.|
| dy | Length | Yes   | Amount to scroll by in the vertical direction. The percentage format is not supported.|
161 162 163


## Example
E
ester.zhou 已提交
164
### Example 1
165 166 167

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

  build() {
    Stack({ alignContent: Alignment.TopStart }) {
      Scroll(this.scroller) {
        Column() {
          ForEach(this.arr, (item) => {
            Text(item.toString())
180 181 182 183 184 185
              .width('90%')
              .height(150)
              .backgroundColor(0xFFFFFF)
              .borderRadius(15)
              .fontSize(16)
              .textAlign(TextAlign.Center)
Z
zengyawen 已提交
186 187 188 189
              .margin({ top: 10 })
          }, item => item)
        }.width('100%')
      }
E
ester.zhou 已提交
190 191 192 193 194
      .scrollable(ScrollDirection.Vertical)  // The scrollbar scrolls in the vertical direction.
      .scrollBar(BarState.On)  // The scrollbar is always displayed.
      .scrollBarColor(Color.Gray)  // Color of the scrollbar.
      .scrollBarWidth(30) // Width of the scrollbar.
      .edgeEffect(EdgeEffect.None)
Z
zengyawen 已提交
195
      .onScroll((xOffset: number, yOffset: number) => {
E
ester.zhou 已提交
196
        console.info(xOffset + ' ' + yOffset)
Z
zengyawen 已提交
197 198
      })
      .onScrollEdge((side: Edge) => {
E
ester.zhou 已提交
199
        console.info('To the edge')
Z
zengyawen 已提交
200 201
      })
      .onScrollEnd(() => {
E
ester.zhou 已提交
202
        console.info('Scroll Stop')
Z
zengyawen 已提交
203
      })
E
ester.zhou 已提交
204

E
ester.zhou 已提交
205 206
      Button('scroll 150')
        .onClick(() => { // Click to scroll down to 150.0 vp.
E
ester.zhou 已提交
207
          this.scroller.scrollBy(0,150)
E
ester.zhou 已提交
208 209
        })
        .margin({ top: 10, left: 20 })
Z
zengyawen 已提交
210
      Button('scroll 100')
E
ester.zhou 已提交
211
        .onClick(() => { // Click to scroll down by 100.0 vp.
E
ester.zhou 已提交
212
          this.scroller.scrollTo({ xOffset: 0, yOffset: this.scroller.currentOffset().yOffset + 100 })
Z
zengyawen 已提交
213
        })
E
ester.zhou 已提交
214
        .margin({ top: 60, left: 20 })
Z
zengyawen 已提交
215
      Button('back top')
E
ester.zhou 已提交
216
        .onClick(() => { // Click to go back to the top.
E
ester.zhou 已提交
217
          this.scroller.scrollEdge(Edge.Top)
Z
zengyawen 已提交
218
        })
E
ester.zhou 已提交
219
        .margin({ top: 110, left: 20 })
Z
zengyawen 已提交
220
      Button('next page')
E
ester.zhou 已提交
221
        .onClick(() => { // Click to go to the next page.
E
ester.zhou 已提交
222
          this.scroller.scrollPage({ next: true })
Z
zengyawen 已提交
223
        })
E
ester.zhou 已提交
224
        .margin({ top: 170, left: 20 })
Z
zengyawen 已提交
225 226 227 228 229
    }.width('100%').height('100%').backgroundColor(0xDCDCDC)
  }
}
```

Z
zengyawen 已提交
230
![en-us_image_0000001256978363](figures/en-us_image_0000001256978363.gif)
E
ester.zhou 已提交
231

E
ester.zhou 已提交
232
### Example 2
233 234 235 236
```ts
@Entry
@Component
struct NestedScroll {
E
ester.zhou 已提交
237
  @State listPosition: number = 0; // 0 indicates scrolling to the top of the list, 1 indicates scrolling to the middle of the list, and 2 indicates scrolling to the bottom of the list.
E
ester.zhou 已提交
238 239
  private arr: number[] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
  private scroller: Scroller = new Scroller()
240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259

  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(() => {
E
ester.zhou 已提交
260
            this.listPosition = 0
261 262
          })
          .onReachEnd(() => {
E
ester.zhou 已提交
263
            this.listPosition = 2
264 265 266
          })
          .onScrollBegin((dx: number, dy: number) => {
            if ((this.listPosition == 0 && dy >= 0) || (this.listPosition == 2 && dy <= 0)) {
E
ester.zhou 已提交
267 268
              this.scroller.scrollBy(0, -dy)
              return { dxRemain: dx, dyRemain: 0 }
269
            }
E
ester.zhou 已提交
270
            this.listPosition = 1
E
ester.zhou 已提交
271
            return { dxRemain: dx, dyRemain: dy };
272 273 274 275 276 277 278 279 280 281 282 283 284 285
          })

          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)