ts-container-scroll.md 10.9 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 9
>  - This component can scroll only when the size on the main axis is less than the content size.
>  - The prerequisite for the component to rebound is that the component is scrolled.
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 27 28 29 30 31
| Name            | Type                                    | Description       |
| -------------- | ---------------------------------------- | --------- |
| scrollable     | ScrollDirection                          | Scroll direction.<br>Default value: **ScrollDirection.Vertical**|
| scrollBar      | [BarState](ts-appendix-enums.md#barstate) | Scrollbar status.<br>Default value: **BarState.Off**|
| scrollBarColor | string \| number \| Color   | Color of the scrollbar.|
| scrollBarWidth | string \| number         | Width of the scrollbar.|
| edgeEffect     | [EdgeEffect](ts-appendix-enums.md#edgeeffect)            | Scroll effect. For details, see **EdgeEffect**.<br>Default value: **EdgeEffect.Spring**|
Z
zengyawen 已提交
32

E
ester.zhou 已提交
33 34 35 36 37 38 39
## ScrollDirection
| Name      | Description                    |
| ---------- | ------------------------ |
| Horizontal | Only horizontal scrolling is supported.    |
| Vertical   | Only vertical scrolling is supported.    |
| None       | Scrolling is disabled.              |
| 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 107
**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.|
| 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 164 165 166


## Example

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

Z
zengyawen 已提交
228
![en-us_image_0000001256978363](figures/en-us_image_0000001256978363.gif)
E
ester.zhou 已提交
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 indicates scrolling to the top of the list, 1 indicates scrolling to the center of the list, and 2 indicates scrolling to the bottom of the 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)