DEV Community

HarmonyOS
HarmonyOS

Posted on

Custom component intercepts the scrolling of the parent component.

Read the original article:Custom component intercepts the scrolling of the parent component

Requirement Description

How to achieve that the parent component Scroll does not respond to scrolling when sliding in a specific area?

Background Knowledge

Scroll, Grid, List, and WaterFlow are all scrollable container components. The general interface enableScrollInteraction of the scroll component can be used to set whether the component supports scroll gestures.
The touch event onTouch is a general event of the component, which triggers this callback when the finger touches the screen. The callback parameters include the following information:
- The type of touch event TouchType, indicating information such as finger press, lift, and slide.
- The information of the screen contact Array, which is the coordinate of the finger on the screen.
- Gesture can bind different types of gesture events to the component and set the response method for the event.

Implementation Steps

Solution 1: Use the touch event onTouch in conjunction with the general interface enableScrollInteraction of the scroll component.
When sliding in a specific area, if the scroll component should not scroll, you need to use onTouch to listen to the touch events in the specific area. In the callback, determine the type of touch event. When the finger presses TouchType.Down or slides TouchType.Move, set the scroll component to be non-scrollable through enableScrollInteraction. When the finger lifts, set the scroll component to support scroll gestures.
The implementation code for the scroll component is similar. Taking the Scroll component as an example-1:

Note: The Scroll component can also control whether it is scrollable through the scrollable interface. Setting it to ScrollDirection.None makes it non-scrollable, while setting it to ScrollDirection.Vertical allows vertical scrolling.
Solution Two: Gesture Event.
Using gesture to bind a swipe gesture event, PanGesture, to a specific area means that when the finger swipes within this area, the swipe event will not be passed to the outer scrollable component. This achieves the effect of the scrollable component not scrolling when swiping within this area.
Most of the code is similar to Solution One, with only the onTouch event replaced by gesture. Take a look to example-2.

It is equivalent to the child component intercepting the scrolling event of the outer scroll component, so there is no need to dynamically modify whether the scroll component supports gesture scrolling through enableScrollInteraction.

Code Snippet

Example-1

@Entry
@Component
struct ScrollExample {
  scroller: Scroller = new Scroller()
  @State scrollEnabled: boolean = true
  @State message: string = 'This text cannot scroll the parent component\'s scroll.'
  private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

  @Styles
  textStyles(){
    .width('90%')
    .height(150)
    .borderRadius(15)
  }

  build() {
    Scroll(this.scroller) {
      Column({ space: 10 }) {
        Text(this.message)
          .backgroundColor(0xE0E0E0)
          .textAlign(TextAlign.Center)
          .textStyles()
          .onTouch((event) => {
            // When the finger is lifted, the scroll resumes.
            if (event.type === TouchType.Cancel || event.type === TouchType.Up) {
              this.scrollEnabled = true // Allow finger sliding
              this.message = 'This text cannot scroll the parent component\'s scroll.'
            }
            // Disable scrolling when fingers are pressed or swiped.
            if (event.type === TouchType.Down || event.type === TouchType.Move) {
              this.scrollEnabled = false // Finger sliding is prohibited.
              this.message = 'Finger pressed down'
            }
          })
        ForEach(this.arr, (item: number) => {
          Text(item.toString())
            .backgroundColor(0xF0F0F0)
            .textAlign(TextAlign.Center)
            .textStyles()
        }, (item: string) => item)
      }
      .width('100%')
    }
    .scrollable(ScrollDirection.Vertical) // Setting the scroll bar direction
    .scrollBar(BarState.On) // The scrollbar is always displayed.
    .enableScrollInteraction(this.scrollEnabled) // Set whether the scroll can be swiped with a finger.
  }
}
Enter fullscreen mode Exit fullscreen mode

Example-2:

// ...
Text(this.message)
  .backgroundColor(0xE0E0E0)
  .textAlign(TextAlign.Center)
  .textStyles()
  .gesture(PanGesture()) // Replace onTouch with gesture
// ...
Enter fullscreen mode Exit fullscreen mode

cke_602.gif

Limitations

This example supports API Version 19 Release and above.
This example supports HarmonyOS 5.1.1 Release SDK and above.
This example requires DevEco Studio 5.1.1 Release and above for compilation and execution.

Written by Dogan Evci

Top comments (0)