DEV Community

HarmonyOS
HarmonyOS

Posted on

How to open a semi-modal pop-up window by dragging

Read the original article:How to open a semi-modal pop-up window by dragging

Requirement Description

How to trigger a half-modal sheet (semi-modal popup) using a drag gesture — for example, pulling upward to reveal a half-modal sheet in a HarmonyOS application.

Background Knowledge

Half-modal transition:
You can bind a half-modal sheet to a component using the bindSheet attribute. When the component is inserted, the size of the half-modal can be defined using either a custom height or the default built-in height. Once triggered (e.g., clicked or dragged), the modal sheet appears.

In addition, the gesture attribute can bind gesture recognition to a component. When a gesture is successfully recognized, the component is notified through event callbacks.
HarmonyOS also allows gesture composition using the GestureGroup() API, supporting sequential, parallel, or exclusive gesture recognition.

Implementation Steps

  1. Make a Text component draggable by setting the draggable(true) property.
  2. Use the bindSheet attribute to bind this component to a half-modal sheet.
  3. Add a gesture listener using the gesture property.
  4. When the user drags the Text component upward, the gesture’s onActionUpdate event is triggered.
  5. Inside this event, set the bound sheet’s isShow attribute to true to display the half-modal sheet.
  6. Optionally, adjust the sheet height dynamically based on the gesture’s offset.

This allows users to pull up a half-modal sheet using a drag motion instead of a click.

Code Snippet / Configuration

@Entry
@Component
struct SheetTransitionExample {
  @State numbers: number[] = []
  @State isShow: boolean = false
  @State sheetHeight: number = 300;

  aboutToAppear() {
    for (let i = 1; i <= 11; i++) {
      this.numbers.push(i)
    }
  }

  @Builder
  myBuilder() {
    Column() {
      List() {
        ForEach(this.numbers, (item: string) => {
          ListItem() {
            Text(item.toString())
              .fontSize(16)
              .textAlign(TextAlign.Center)
              .size({ height: 20, width: '100%' })
          }.margin(10)
          .borderRadius(10)
          .backgroundColor('#ffdda63b')
        }, (item: string) => item)
          .onMove((from: number, to: number) => {
            let tmp = this.numbers.splice(from, 1);
            this.numbers.splice(to, 0, tmp[0])
          })
      }
      .lanes({ minLength: 80, maxLength: 400 })
      .width('100%')
      .height('100%')
      .backgroundColor('#ff9fb0cd')
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#0D182431')
    .padding({ top: 5 })
  }

  build() {
    Column() {
      Text('Drag Up')
        .draggable(true)
        .fontSize(20)
        .fontColor(Color.Black)
        .margin(10)
        .bindSheet($$this.isShow, this.myBuilder(), {
          height: this.sheetHeight,
          backgroundColor: Color.Blue,
          blurStyle: BlurStyle.Thick,
          showClose: true,
          title: { title: 'Title', subtitle: 'Subtitle' },
        })
        .gesture(
          GestureGroup(GestureMode.Sequence,
            PanGesture({ fingers: 1, direction: null, distance: 0 })
              .onActionUpdate((event: GestureEvent) => {
                this.isShow = true
                console.info('Output:', event.offsetY)
                this.sheetHeight = Math.abs(event.offsetY)
              })
          )
        )
    }
    .justifyContent(FlexAlign.End)
    .width('100%')
    .height('100%')
    .backgroundColor(Color.White)
  }
}
Enter fullscreen mode Exit fullscreen mode

Test Results

  • The drag gesture successfully triggers the half-modal sheet to appear.
  • The sheet’s height dynamically responds to the drag distance.
  • The app compiles and runs correctly without code errors.

gif.gif

Limitations or Considerations

  • This example supports API Version 19 Release and above.
  • Requires HarmonyOS 5.1.1 Release SDK or later.
  • Must be built and run using DevEco Studio 5.1.1 Release or later.

Related Documents or Links

https://developer.huawei.com/consumer/en/doc/harmonyos-references/ts-universal-attributes-sheet-transition#bindsheet

Written by Emine Inan

Top comments (0)