1# Scroll 2 3The **\<Scroll>** component scrolls the content when the layout size of a component exceeds the size of its parent component. 4 5> **NOTE** 6> - This component is supported since API version 7. Updates will be marked with a superscript to indicate their earliest API version. 7> - 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>**. 8> - This component can scroll only when the size on the main axis is less than the content size. 9> - This component can produce a bounce effect only when there is more than one screen of content. 10 11 12## Child Components 13 14This component supports only one child component. 15 16 17## APIs 18 19Scroll(scroller?: Scroller) 20 21**Parameters** 22 23| Name| Type| Mandatory| Description| 24| -------- | -------- | -------- | -------- | 25| scroller | [Scroller](#scroller) | No| Scroller, which can be bound to scrollable components.| 26 27## Attributes 28 29In addition to the [universal attributes](ts-universal-attributes-size.md), the following attributes are supported. 30 31| Name | Type | Description | 32| -------------- | ---------------------------------------- | --------- | 33| scrollable | [ScrollDirection](#scrolldirection) | Scroll direction.<br>Default value: **ScrollDirection.Vertical**| 34| scrollBar | [BarState](ts-appendix-enums.md#barstate) | Scrollbar status.<br>Default value: **BarState.Auto**| 35| scrollBarColor | string \| number \| [Color](ts-appendix-enums.md#color) | Color of the scrollbar.| 36| scrollBarWidth | string \| number | Width of the scrollbar.| 37| edgeEffect | [EdgeEffect](ts-appendix-enums.md#edgeeffect) | Scroll effect. For details, see **EdgeEffect**.<br>Default value: **EdgeEffect.None**| 38 39## ScrollDirection 40| Name | Description | 41| ---------- | ------------------------ | 42| Horizontal | Only horizontal scrolling is supported. | 43| Vertical | Only vertical scrolling is supported. | 44| None | Scrolling is disabled. | 45| Free<sup>(deprecated)</sup> | Vertical or horizontal scrolling is supported.<br>This API is deprecated since API version 9. | 46 47## Events 48 49| Name | Description | 50| ------------------------------------------------------------ | ------------------------------------------------------------ | 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.| 52| onScroll(event: (xOffset: number, yOffset: number) => void) | Triggered to return the horizontal and vertical offsets during scrolling when the specified scroll event occurs. | 53| onScrollEdge(event: (side: Edge) => void) | Triggered when scrolling reaches the edge. | 54| onScrollEnd<sup>(deprecated) </sup>(event: () => void) | Triggered when scrolling stops.<br>This event is deprecated since API version 9. Use the **onScrollStop** event instead. | 55| 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.| 56| 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** 59> 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**. 61 62## Scroller 63 64Implements 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>**. 65 66 67### Objects to Import 68 69``` 70scroller: Scroller = new Scroller() 71``` 72 73 74### scrollTo 75 76scrollTo(value: { xOffset: number | string, yOffset: number | string, animation?: { duration: number, curve: Curve } }): void 77 78 79Scrolls to the specified position. 80 81**Parameters** 82 83| Name | Type | Mandatory| Description | 84| --------- | ------------------------------------------------------------ | ---- | ------------------------------------------------------------ | 85| xOffset | number | string | Yes | Horizontal scrolling offset. | 86| yOffset | number | string | Yes | Vertical scrolling offset. | 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.| 88 89 90### scrollEdge 91 92scrollEdge(value: Edge): void 93 94 95Scrolls 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. 96 97**Parameters** 98 99| Name | Type| Mandatory | Description | 100| ----- | ---- | ---- | --------- | 101| value | [Edge](ts-appendix-enums.md#edge) | Yes | Edge position to scroll to.| 102 103 104### scrollPage 105 106scrollPage(value: { next: boolean, direction?: Axis }): void 107 108Scrolls to the next or previous page. 109 110**Parameters** 111 112| Name | Type | Mandatory | Description | 113| --------- | ------- | ---- | ------------------------------ | 114| 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.| 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. | 116 117 118### currentOffset 119 120currentOffset(): { xOffset: number, yOffset: number } 121 122 123Obtains the scrolling offset. 124 125**Return value** 126 127| Type | Description | 128| ---------------------------------------- | ---------------------------------------- | 129| {<br>xOffset: number,<br>yOffset: number<br>} | **xOffset**: horizontal scrolling offset.<br>**yOffset**: vertical scrolling offset.| 130 131 132### scrollToIndex 133 134scrollToIndex(value: number): void 135 136 137Scrolls to the item with the specified index. 138 139 140> **NOTE** 141> 142> Only the **\<Grid>** and **\<List>** components are supported. 143 144**Parameters** 145 146| Name| Type| Mandatory| Description | 147| ------ | -------- | ---- | ---------------------------------- | 148| value | number | Yes | Index of the item to be scrolled to in the list.| 149 150 151### scrollBy<sup>9+</sup> 152 153scrollBy(dx: Length, dy: Length): void 154 155 156Scrolls by the specified amount. 157 158 159> **NOTE** 160> 161> Only the **\<Scroll>**, **\<ScrollBar>**, **\<Grid>**, and **\<List>** components are supported. 162 163**Parameters** 164 165| Name | Type | Mandatory | Description | 166| ----- | ------ | ---- | ----------------- | 167| dx | Length | Yes | Amount to scroll by in the horizontal direction. The percentage format is not supported.| 168| dy | Length | Yes | Amount to scroll by in the vertical direction. The percentage format is not supported.| 169 170 171## Example 172### Example 1 173 174```ts 175// xxx.ets 176@Entry 177@Component 178struct ScrollExample { 179 scroller: Scroller = new Scroller() 180 private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 181 182 build() { 183 Stack({ alignContent: Alignment.TopStart }) { 184 Scroll(this.scroller) { 185 Column() { 186 ForEach(this.arr, (item) => { 187 Text(item.toString()) 188 .width('90%') 189 .height(150) 190 .backgroundColor(0xFFFFFF) 191 .borderRadius(15) 192 .fontSize(16) 193 .textAlign(TextAlign.Center) 194 .margin({ top: 10 }) 195 }, item => item) 196 }.width('100%') 197 } 198 .scrollable(ScrollDirection.Vertical) // The scrollbar scrolls in the vertical direction. 199 .scrollBar(BarState.On) // The scrollbar is always displayed. 200 .scrollBarColor(Color.Gray) // Color of the scrollbar. 201 .scrollBarWidth(30) // Width of the scrollbar. 202 .edgeEffect(EdgeEffect.None) 203 .onScroll((xOffset: number, yOffset: number) => { 204 console.info(xOffset + ' ' + yOffset) 205 }) 206 .onScrollEdge((side: Edge) => { 207 console.info('To the edge') 208 }) 209 .onScrollEnd(() => { 210 console.info('Scroll Stop') 211 }) 212 213 Button('scroll 150') 214 .onClick(() => { // Click to scroll down to 150.0 vp. 215 this.scroller.scrollBy(0,150) 216 }) 217 .margin({ top: 10, left: 20 }) 218 Button('scroll 100') 219 .onClick(() => { // Click to scroll down by 100.0 vp. 220 this.scroller.scrollTo({ xOffset: 0, yOffset: this.scroller.currentOffset().yOffset + 100 }) 221 }) 222 .margin({ top: 60, left: 20 }) 223 Button('back top') 224 .onClick(() => { // Click to go back to the top. 225 this.scroller.scrollEdge(Edge.Top) 226 }) 227 .margin({ top: 110, left: 20 }) 228 Button('next page') 229 .onClick(() => { // Click to go to the next page. 230 this.scroller.scrollPage({ next: true }) 231 }) 232 .margin({ top: 170, left: 20 }) 233 }.width('100%').height('100%').backgroundColor(0xDCDCDC) 234 } 235} 236``` 237 238 239 240### Example 2 241```ts 242@Entry 243@Component 244struct NestedScroll { 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. 246 private arr: number[] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 247 private scrollerForScroll: Scroller = new Scroller() 248 private scrollerForList: Scroller = new Scroller() 249 250 build() { 251 Flex() { 252 Scroll(this.scrollerForScroll) { 253 Column() { 254 Text("Scroll Area") 255 .width("100%").height("40%").backgroundColor(0X330000FF) 256 .fontSize(16).textAlign(TextAlign.Center) 257 .onClick(() => { 258 this.scrollerForList.scrollToIndex(5) 259 }) 260 261 List({ space: 20, scroller: this.scrollerForList }) { 262 ForEach(this.arr, (item) => { 263 ListItem() { 264 Text("ListItem" + item) 265 .width("100%").height("100%").borderRadius(15) 266 .fontSize(16).textAlign(TextAlign.Center).backgroundColor(Color.White) 267 }.width("100%").height(100) 268 }, item => item) 269 } 270 .width("100%") 271 .height("50%") 272 .edgeEffect(EdgeEffect.None) 273 .onReachStart(() => { 274 this.listPosition = 0 275 }) 276 .onReachEnd(() => { 277 this.listPosition = 2 278 }) 279 .onScrollFrameBegin((offset: number) => { 280 if ((this.listPosition == 0 && offset <= 0) || (this.listPosition == 2 && offset >= 0)) { 281 this.scrollerForScroll.scrollBy(0, offset) 282 return { offsetRemain: 0 } 283 } 284 this.listPosition = 1 285 return { offsetRemain: offset }; 286 }) 287 288 Text("Scroll Area") 289 .width("100%").height("40%").backgroundColor(0X330000FF) 290 .fontSize(16).textAlign(TextAlign.Center) 291 } 292 } 293 .width("100%").height("100%") 294 }.width('100%').height('100%').backgroundColor(0xDCDCDC).padding(20) 295 } 296} 297``` 298 299 300