[Daily HarmonyOS Next Knowledge] Routing Tables, Lazy Load List UI Refresh, Split-Screen Adaptation, Custom Pop-up and Soft Keyboard Spacing, New Routing Support for Landscape Mode
1. HarmonyOS System Routing Table - Home Page Cannot Listen for Page Display and Hide?
Reference: https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/arkts-navigation-navigation-V5
Scenario: Routing jumps as follows: Index → PageOne, click back from PageOne.
Code:
@Entry
@Component
struct Index {
pageStack: NavPathStack = new NavPathStack();
build() {
Navigation(this.pageStack) {
}.onAppear(() => {
this.pageStack.pushPathByName("PageOne", null, false);
})
.hideNavBar(true)
}
onPageShow(): void {
console.log('onPageShow')
}
onPageHide(): void {
console.log('onPageHide')
}
}
Issue: When jumping from Index to PageOne, onPageHide
is not called back. When returning from PageOne to Index, onPageShow
is not called back.
Question: How to listen for the display and hiding of the Index page? (When Index jumps to PageOne via router, normal page callbacks are visible.)
Solution: Use NavPathStack with the navDestination attribute for page routing, which can carry page information. NavDestination has related onShown
and onHidden
methods. Refer to:
- NavPathStack documentation: https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/ts-basic-components-navigation-V5#navpathstack10
The onPageShow()
method only takes effect in custom components decorated with @Entry and cannot be triggered when returning to subpages of NavDestination wrapped by Navigation. To listen for the display and hiding of the main page upon return, handle business logic in the callback by listening to the Navigation's onNavBarStateChange()
event. Reference:
https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-basic-components-navigation
2. HarmonyOS LazyForEach UI Refresh Issue?
Scenario: When using LazyForEach to traverse and generate different entries in the home page List control, the key generation uses business id + index.
- The first entry is a carousel with business id 1 and index 1.
- When the operation background adds resources to the carousel, the business id remains 1, but an additional image is configured for the carousel.
- When notifying the array, the carousel control does not refresh.
Question: How to handle this? Should a random number be added when generating keys?
Solution: The List refresh strategy is based on bound keys, which correspond to the component tree and refresh the page by updating virtual components. Since adding images does not change the key, the refresh mechanism is not triggered. Adding a random number causes refresh on each load, affecting performance. It is recommended to use JSON.stringify(item) + id + index
as the key.
3. HarmonyOS Split-Screen Adaptation: Can the Navigation Area Support Multiple PageStacks Based on TabBar to Maintain Page Stacks?
Requirement: For split-screen adaptation, can the navigation area support multiple PageStacks
based on TabBar to maintain page stacks? The effect is similar to xxx devices, where each TabBar corresponds to a PageStack
, and switching TabBars restores the corresponding Tab's page stack.
Reference structure:
Tabs() {
TabContent() {
contentOne()
}.tabBar('Discover')
TabContent() {
contentTwo()
}.tabBar('Mall')
.backgroundColor(Color.Pink)
}.barPosition(BarPosition.End)
.vertical(false) // Set tab layout direction to horizontal
.barMode(BarMode.Fixed) // All sub-tabs equally divide the tab bar width, and the tab bar is not scrollable
4. HarmonyOS Custom Pop-up and Soft Keyboard Spacing?
Issue: A dialog is set at the bottom with a TextInput. When the pop-up is opened, there is spacing between the pop-up and the soft keyboard. The expectation is for the pop-up to be flush with the soft keyboard. Setting the offset dy has no effect.
Solution: Adjust the pop-up position by setting customStyle
to true and adding an offset to the column layout inside the pop-up: .offset({ x: 0, y: xx })
.
5. HarmonyOS: Is There a Way to Apply Landscape Mode Only to a New Route While Other Routes Remain in Portrait Mode?
Scenario: When switching from a portrait page to landscape mode by opening a new route, the current landscape implementation sets landscape mode in the new route page using lastWindow.setPreferredOrientation(window.Orientation.LANDSCAPE)
. This causes an issue where the original portrait primary page is simultaneously changed to landscape, and the original landscape secondary page is changed to portrait, which is visible during route page transitions and considered a defect by our testing team.
Requirement: When jumping to a secondary landscape page, can we directly open a route container that is already in landscape mode without affecting the primary portrait page?
Steps:
Open the
module.json5
file under entry and add anorientation
attribute to theabilities
node:"orientation": 'unspecified'
.First page:
import { router } from '@kit.ArkUI';
@Entry
@Component
struct aboutScreen1 {
@State message: string = '';
build() {
Column() {
Text('Home Page, click to jump')
.fontSize(30)
.textAlign(TextAlign.Center)
.width('100%')
.fontWeight(500)
.height('100%')
.onClick(() => {
router.pushUrl({ url: "pages/aboutScreen2" })
})
}
.justifyContent(FlexAlign.Center)
.width('100%')
.backgroundColor(Color.White)
.height('100%')
}
}
- Second page:
import { router, window } from '@kit.ArkUI';
import { BusinessError } from '@kit.BasicServicesKit';
@Entry
@Component
struct aboutScreen2 {
@State message: string = '';
aboutToAppear(): void {
let orientation = window.Orientation.LANDSCAPE
this.setScreenOrientation(orientation)
}
aboutToDisappear(): void {
let orientation = window.Orientation.PORTRAIT
this.setScreenOrientation(orientation)
}
setScreenOrientation(orientation: window.Orientation) {
let windowClass: window.Window | undefined = undefined;
try {
let promise = window.getLastWindow(getContext())
promise.then((data) => {
windowClass = data
windowClass.setPreferredOrientation(orientation)
}).catch((err: BusinessError) => {
console.error('getLastWindow error')
})
} catch (e) {
console.error('setScreenOrientation error')
}
}
build() {
Column() {
Text('I am in landscape!')
.fontSize(30)
.textAlign(TextAlign.Center)
.width('100%')
.fontWeight(500)
.height('50%')
}
.justifyContent(FlexAlign.Center)
.width('100%')
.backgroundColor(Color.White)
.height('100%')
}
}
Top comments (0)