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%')
}
}
- 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%')
}
}
Test Results
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.

Top comments (0)