DEV Community

HarmonyOS
HarmonyOS

Posted on

How to Listen for Navigation Route Page Switching Events

Read the original article:How to Listen for Navigation Route Page Switching Events

Requirement Description

How can we listen for Navigation page switching events in order to perform custom operations during page transitions — such as obtaining information about the entering and exiting pages, or intercepting the switch itself?

Background Knowledge

  • @ohos.arkui.observer (Observer) provides the capability to silently observe UI component behavior changes, such as page lifecycle, component visibility, and scroll events. Among them, uiObserver.on('navDestinationSwitch') can listen for Navigation page switching events and execute custom operations.
  • setInterception: Used to set up a callback for Navigation route interception. Through the setInterception method, route interception can be implemented for unified handling of pre-navigation logic checks (such as login state validation or page state management).

Implementation Steps

Solution 1: Use the uiObserver.on('navDestinationSwitch') method to listen for Navigation page switching events. You can configure a callback function for page switching in the parameters.

Solution 2: Use the setInterception method of the navigation controller NavPathStack. In the parameter NavigationInterception, you can set up callbacks for interception before and after navigation. The example below demonstrates pre-navigation interception.

Code Snippet / Configuration (fontsize: h3)

Solution 1:

import { uiObserver } from '@kit.ArkUI';

function callBackFunc(info: uiObserver.NavDestinationSwitchInfo) {
  let from = JSON.stringify(info.from)
  let to = JSON.stringify(info.to)
  console.info(`from:${from} -------- to: ${to}`);
}

@Entry
@Component
struct NavObserverDemo {
  private stack: NavPathStack = new NavPathStack();

  @Builder
  Page(name: string) {
    PageOne()
  }

  aboutToAppear() {
    uiObserver.on('navDestinationSwitch', this.getUIContext(), callBackFunc); // Register listener for page switching
  }

  aboutToDisappear() {
    uiObserver.off('navDestinationSwitch', this.getUIContext(), callBackFunc);
  }

  build() {
    Navigation(this.stack) {
      Button('Back').onClick(() => {
        this.stack.pushPath({ name: 'pageOne' });
      })
    }
    .title('Navigation')
    .navDestination(this.Page)
  }
}

@Component
export struct PageOne {
  build() {
    NavDestination() {
      Text('pageOne')
    }.title('pageOne')
  }
}
Enter fullscreen mode Exit fullscreen mode

Runtime result:

I from:"navBar" -------- to: {"navigationId":"","name":"pageOne","state":0,"index":0,"navDestinationId":"0","mode":0,"uniqueId":17}

I from:{"navigationId":"","name":"pageOne","state":1,"index":0,"navDestinationId":"0","mode":0,"uniqueId":17} -------- to: "navBar"

Solution 2:

@Entry
@Component
struct Index {
  pathStack: NavPathStack = new NavPathStack();

  aboutToAppear(): void {
    this.pathStack.setInterception({
      willShow: (from: NavDestinationContext | 'navBar', to: NavDestinationContext | 'navBar',
        operation: NavigationOperation, animated: boolean) => {
        if (typeof from === 'string') {
          let target = to as NavDestinationContext
          console.info(`from page is navigation home -> ${target.pathInfo.name}`);
        } else if (typeof to === 'string') {
          let target = from as NavDestinationContext
          console.info(`${target.pathInfo.name} -> to page is navigation home`);
        }
      }
    })
  }

  @Builder
  pageMap(name: string) {
    PageOne()
  }

  build() {
    Navigation(this.pathStack) {
      Column({ space: 30 }) {
        Text('PageOne')
        Button('Back')
          .onClick(() => {
            this.pathStack.pushPathByName('PageOne', null, false);
          })
      }
    }.navDestination(this.pageMap)
  }
}

@Component
struct PageOne {
  pathStack: NavPathStack = new NavPathStack();

  build() {
    NavDestination() {
      Column({ space: 30 }) {
        Text('PageOne')
        Button('Back')
          .onClick(() => {
            this.pathStack.pop();
          })
      }
    }.title('PageOne')
    .onReady((context: NavDestinationContext) => {
      this.pathStack = context.pathStack;
    })
  }
}
Enter fullscreen mode Exit fullscreen mode

Runtime result:

I from page is navigation home -> PageOne

I PageOne -> to page is navigation home

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)