DEV Community

HarmonyOS
HarmonyOS

Posted on

bindSheet: How to Maintain Its State After Navigation and Return

Read the original article:bindSheet: How to Maintain Its State After Navigation and Return

Requirement Description

The content of bindSheet is a List. When clicking a ListItem to navigate to another page, how can we ensure that upon returning from the other page, bindSheet remains open and the List stays in its original state?

Background Knowledge

By default, bindSheet is a non-fullscreen modal popup interaction page that allows part of the underlying parent view to remain visible, helping users retain their parent view context during semi-modal interactions.

AppStorage is a global UI state storage center bound to the application process. It is created by the UI framework when the app starts and stores UI state data in runtime memory to enable application-level global state sharing.

Implementation Steps

In the onPageShow lifecycle, retrieve the current bindSheet visibility state and List scroll position through AppStorage. When navigating to another page, record the current List scroll position. When returning from the target page, set the variable bound to the bindSheet visibility state to true. In the List’s onAppear method, use the Scroller to scroll to the previously saved position, thus keeping the UI unchanged.

Code Snippet

  • Index.ets
  import { window } from '@kit.ArkUI';

  @Entry
  @Component
  struct SheetTransitionExample {
    @State isShow: boolean | undefined = false
    @State sheetHeight: number = 200  ;
    @State text: string = 'xxxxx'
    @State numArr: number[] = []
    private scrollerForList: Scroller = new Scroller()
    @State currentY: number | undefined = 0

    onPageShow(): void {
      this.isShow = AppStorage.get('istrue')
      this.currentY = AppStorage.get('currenty')
      AppStorage.setOrCreate('istrue', false)
      AppStorage.setOrCreate('currenty', 0)
      // Immersive mode
      window.getLastWindow(this.getUIContext().getHostContext(), (err, win) => {
        win.setWindowLayoutFullScreen(true)
      })
    }

    aboutToAppear(): void {
      for (let index = 0; index < 20; index++) {
        this.numArr.push(index)
      }
    }

    @Builder
    myBuilder() {
      List({ scroller: this.scrollerForList }) {
        ForEach(this.numArr, (item: number) => {
          ListItem() {
            Column() {
              Text(item.toString())
                .fontColor(Color.Black)
            }
            .justifyContent(FlexAlign.Center)
            .height('50')
            .width('100%')
            .backgroundColor('#F3F3F3')
            .onClick(() => {
              AppStorage.setOrCreate('currenty', this.scrollerForList.currentOffset().yOffset)
              this.getUIContext().getRouter().pushUrl({
                url: 'pages/Page'
              })
            })
          }
        })
      }.onAppear(() => {
        this.scrollerForList.scrollTo({ xOffset: 0, yOffset: this.currentY })
      })
      .width('100%')
      .height('100%')
    }

    build() {
      Column() {
        Button('transition modal 1')
          .onClick(() => {
            this.isShow = true
          })
          .fontSize(20)
          .margin(10)
          .bindSheet($$this.isShow, this.myBuilder(), {
            height: this.sheetHeight,
            onAppear: () => {
              console.info('BindSheet onAppear.')
            },
            onDisappear: () => {
              console.info('BindSheet onDisappear.')
            }
          })
      }
      .backgroundColor('#F1F3F5')
      .justifyContent(FlexAlign.Center)
      .width('100%')
      .height('100%')
    }
  }
Enter fullscreen mode Exit fullscreen mode
  • Page.ets
  import { window } from '@kit.ArkUI';

  @Entry
  @Component
  struct Page {
    @State message: string = 'Hello World';

    onBackPress() {
      AppStorage.setOrCreate('istrue', true)
    }

    onPageShow(): void {
      // Immersive mode
      window.getLastWindow(this.getUIContext().getHostContext(), (err, win) => {
        win.setWindowLayoutFullScreen(true)
      })
    }

    build() {
      Column() {
        Text(this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
          .onClick(() => {
            AppStorage.setOrCreate('istrue', true)
            this.getUIContext().getRouter().back()
          })
      }
      .backgroundColor('#F1F3F5')
      .justifyContent(FlexAlign.Center)
      .width('100%')
      .height('100%')
    }
  }
Enter fullscreen mode Exit fullscreen mode

Test Results

cke_1948.gif

Limitations or Considerations

This example supports API Version 19 Release and above.

This example supports HarmonyOS 5.1.1 Release SDK and above.

This example must be compiled and run using DevEco Studio 5.1.1 Release or later.

Written by Bunyamin Akcay

Top comments (0)