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

## APIs

Scroll(scroller?: Scroller)

E
ester.zhou 已提交
21 22 23 24 25 26
**Parameters**

| Name| Type| Mandatory| Description|
| -------- | -------- | -------- | -------- |
| scroller | [Scroller](#scroller) | No| Scroller, which can be bound to scrollable components.|

Z
zengyawen 已提交
27 28
## Attributes

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

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

E
ester.zhou 已提交
39 40 41 42 43 44
## ScrollDirection
| Name      | Description                    |
| ---------- | ------------------------ |
| Horizontal | Only horizontal scrolling is supported.    |
| Vertical   | Only vertical scrolling is supported.    |
| None       | Scrolling is disabled.              |
E
ester.zhou 已提交
45
| Free<sup>(deprecated)</sup> | Vertical or horizontal scrolling is supported.<br>This API is deprecated since API version 9. |
E
esterzhou 已提交
46

47 48
## Events

E
ester.zhou 已提交
49 50
| Name                                                        | Description                                                    |
| ------------------------------------------------------------ | ------------------------------------------------------------ |
E
ester.zhou 已提交
51
| onScrollFrameBegin<sup>9+</sup>(event: (offset: number, state: ScrollState) => { offsetRemain }) | Triggered when each frame scrolling starts. The input parameters indicate the amount by which the **\<Scroll>** component will scroll. The event handler then works out the amount by which the component needs to scroll based on the real-world situation and returns the result.<br>\- **offset**: amount to scroll by.<br>\- **state**: current scrolling status.<br>- **offsetRemain**: actual amount by which the component scrolls.|
E
ester.zhou 已提交
52 53
| onScroll(event: (xOffset: number, yOffset: number) => void)  | Triggered to return the horizontal and vertical offsets during scrolling when the specified scroll event occurs.         |
| onScrollEdge(event: (side: Edge) => void)                    | Triggered when scrolling reaches the edge.                                        |
E
ester.zhou 已提交
54 55 56
| onScrollEnd<sup>(deprecated) </sup>(event: () => void)                               | Triggered when scrolling stops.<br>This event is deprecated since API version 9. Use the **onScrollStop** event instead.    |
| onScrollStart<sup>9+</sup>(event: () => void) | Triggered when scrolling starts and is initiated by the user's finger dragging the **\<Scroll>** component or its scrollbar. This event is also triggered when the animation contained in the scrolling triggered by [Scroller](#scroller) starts.|
| onScrollStop<sup>9+</sup>(event: () => void) | Triggered when scrolling stops after the user's finger leaves the screen. This event is also triggered when the animation contained in the scrolling triggered by [Scroller](#scroller) stops.|
57 58

>  **NOTE**
E
ester.zhou 已提交
59
>
E
ester.zhou 已提交
60
>  If the **onScrollFrameBegin** event and **scrollBy** method are used to implement nested scrolling, set the **edgeEffect** attribute of the scrollable child component to **None**. For example, if a **\<List>** is nested in the **\<Scroll>** component, **edgeEffect** of the **\<List>** must be set to **EdgeEffect.None**.
Z
zengyawen 已提交
61 62 63

## Scroller

E
ester.zhou 已提交
64
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. One controller can control only one container component. The supported container components are **\<List>**, **\<Scroll>**, **\<ScrollBar>**, **\<Grid>**, and **\<WaterFlow>**.
Z
zengyawen 已提交
65 66 67 68


### Objects to Import

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

Scrolls to the specified position.

E
ester.zhou 已提交
81
**Parameters**
Z
zengyawen 已提交
82

E
ester.zhou 已提交
83 84
| Name   | Type                                                    | Mandatory| Description                                                    |
| --------- | ------------------------------------------------------------ | ---- | ------------------------------------------------------------ |
E
ester.zhou 已提交
85 86
| xOffset   | number | string                                              | Yes  | Horizontal scrolling offset.                                              |
| yOffset   | number | string                                              | Yes  | Vertical scrolling offset.                                              |
E
ester.zhou 已提交
87
| animation | {<br>duration: number,<br>curve: [Curve](ts-appendix-enums.md#curve)<br>} | No  | Animation configuration, which includes the following:<br>- **duration**: scrolling duration.<br>- **curve**: scrolling curve.|
Z
zengyawen 已提交
88 89


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

scrollEdge(value: Edge): void

Z
zengyawen 已提交
94

E
ester.zhou 已提交
95
Scrolls to the edge of the container, regardless of the scroll axis direction. **Edge.Top** and **Edge.Start** produce the same effect, and **Edge.Bottom** and **Edge.End** produce the same effect.
Z
zengyawen 已提交
96

E
ester.zhou 已提交
97
**Parameters**
Z
zengyawen 已提交
98

E
ester.zhou 已提交
99 100 101
| Name  | Type| Mandatory  | Description     |
| ----- | ---- | ---- | --------- |
| value | [Edge](ts-appendix-enums.md#edge) | Yes   | Edge position to scroll to.|
E
ester.zhou 已提交
102

Z
zengyawen 已提交
103

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

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

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

E
ester.zhou 已提交
110 111 112 113 114
**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 已提交
115
| 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 已提交
116 117


118
### currentOffset
Z
zengyawen 已提交
119

E
ester.zhou 已提交
120
currentOffset(): { xOffset: number, yOffset: number }
Z
zengyawen 已提交
121

Z
zengyawen 已提交
122 123 124

Obtains the scrolling offset.

E
ester.zhou 已提交
125
**Return value**
Z
zengyawen 已提交
126

E
ester.zhou 已提交
127 128 129
| Type                                      | Description                                      |
| ---------------------------------------- | ---------------------------------------- |
| {<br>xOffset: number,<br>yOffset: number<br>} | **xOffset**: horizontal scrolling offset.<br>**yOffset**: vertical scrolling offset.|
Z
zengyawen 已提交
130

Z
zengyawen 已提交
131

E
ester.zhou 已提交
132
### scrollToIndex
Z
zengyawen 已提交
133

E
ester.zhou 已提交
134
scrollToIndex(value: number): void
Z
zengyawen 已提交
135 136


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

Z
zengyawen 已提交
139

E
ester.zhou 已提交
140
>  **NOTE**
E
ester.zhou 已提交
141
>
E
ester.zhou 已提交
142
>  Only the **\<Grid>** and **\<List>** components are supported.
Z
zengyawen 已提交
143

E
ester.zhou 已提交
144
**Parameters**
Z
zengyawen 已提交
145

E
ester.zhou 已提交
146 147 148
| Name| Type| Mandatory| Description                          |
| ------ | -------- | ---- | ---------------------------------- |
| value  | number   | Yes  | Index of the item to be scrolled to in the list.|
Z
zengyawen 已提交
149 150


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

153
scrollBy(dx: Length, dy: Length): void
Z
zengyawen 已提交
154 155


156
Scrolls by the specified amount.
Z
zengyawen 已提交
157

Z
zengyawen 已提交
158

159
>  **NOTE**
E
ester.zhou 已提交
160
>
E
ester.zhou 已提交
161
>  Only the **\<Scroll>**, **\<ScrollBar>**, **\<Grid>**, and **\<List>** components are supported.
162

E
ester.zhou 已提交
163
**Parameters**
164

E
ester.zhou 已提交
165 166 167 168
| 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.|
169 170 171


## Example
E
ester.zhou 已提交
172
### Example 1
173 174 175

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

  build() {
    Stack({ alignContent: Alignment.TopStart }) {
      Scroll(this.scroller) {
        Column() {
          ForEach(this.arr, (item) => {
            Text(item.toString())
188 189 190 191 192 193
              .width('90%')
              .height(150)
              .backgroundColor(0xFFFFFF)
              .borderRadius(15)
              .fontSize(16)
              .textAlign(TextAlign.Center)
Z
zengyawen 已提交
194 195 196 197
              .margin({ top: 10 })
          }, item => item)
        }.width('100%')
      }
E
ester.zhou 已提交
198 199 200 201 202
      .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 已提交
203
      .onScroll((xOffset: number, yOffset: number) => {
E
ester.zhou 已提交
204
        console.info(xOffset + ' ' + yOffset)
Z
zengyawen 已提交
205 206
      })
      .onScrollEdge((side: Edge) => {
E
ester.zhou 已提交
207
        console.info('To the edge')
Z
zengyawen 已提交
208 209
      })
      .onScrollEnd(() => {
E
ester.zhou 已提交
210
        console.info('Scroll Stop')
Z
zengyawen 已提交
211
      })
E
ester.zhou 已提交
212

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

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

E
ester.zhou 已提交
240
### Example 2
241 242 243 244
```ts
@Entry
@Component
struct NestedScroll {
E
ester.zhou 已提交
245
  @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 已提交
246
  private arr: number[] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
E
ester.zhou 已提交
247 248
  private scrollerForScroll: Scroller = new Scroller()
  private scrollerForList: Scroller = new Scroller()
249 250 251

  build() {
    Flex() {
E
ester.zhou 已提交
252
      Scroll(this.scrollerForScroll) {
253 254 255 256
        Column() {
          Text("Scroll Area")
            .width("100%").height("40%").backgroundColor(0X330000FF)
            .fontSize(16).textAlign(TextAlign.Center)
E
ester.zhou 已提交
257 258 259
            .onClick(() => {
              this.scrollerForList.scrollToIndex(5)
            })
260

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

          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)