HarmonyOS 鸿蒙Next开发案例 | 封装router方法造个轮子实现获取应用内部页面跳转来源功能

HarmonyOS 鸿蒙Next开发案例 | 封装router方法造个轮子实现获取应用内部页面跳转来源功能 场景介绍

在一些应用开发过程中涉及多个页面跳转的场景,从当前页面跳转到多个不同的子页面,从子页面返回时,需要根据从不同的页面进行逻辑处理。本文基于ohos.router已有的能力,封装所有router方法,实现获取应用内部页面跳转来源功能,提高页面开发效率。

效果呈现

运行环境

本例基于以下环境开发,开发者也可以基于其他适配的版本进行开发:

  • IDE: DevEco Studio 3.1.1 Release
  • SDK: 3.1.0(API 9)

实现思路

  • 跳转来源和传递参数的变化:创建一个公共工具类RouterManager,用于封装router相关方法。
  • 页面的跳转:使用pushUrl方法跳转到应用内的目标页面同时需要更新referrer属性。对于目标页面来说,跳转来源就是当前页面url。
  • 页面跳转来源:通过referrer的get方法就可以直接获取当前页面的跳转来源。
  • 页面的返回:使用back方法返回上一页面时,也需要更新referrer。相对于指定页面来说,跳转来源就是当前页面url。

开发步骤

  1. 由于创建公共工具类RouterManager,因此需要创建一个model包,将其属性(方法)和router函数对所有实例共享。

    具体代码如下:

    // ets/model/RouterManager.ts
    import router from '[@ohos](/user/ohos).router';
    class RouterManager {
    
      private static instance: RouterManager = null;
      private referrer: string;
    
      //获取RouterManager单例     
      static getInstance(): RouterManager {
        if(!RouterManager.instance) {
          RouterManager.instance = new RouterManager();
        }
        return RouterManager.instance;
      }
      //获取当前页面的URL     
      getUrl(): string {
        const  curPageState: router.RouterState = this.getState();
        return curPageState.path + curPageState.name;
      }    
      // 设置referrer
      // @param referrer     
      setReferrer(referrer: string) {
        this.referrer = referrer;
      }   
      //获取当前页面的跳转来源    
      getReferrer(): string {
        return this.referrer;
      }   
      // 跳转到应用内的指定页面options.url
      //@param options    
      pushUrl(options: router.RouterOptions, mode = router.RouterMode.Standard): Promise<void> {
        if (!options || !options.url) { // options必选参数
          return Promise.reject('option or url is null/undefined');
        }
        // 页面跳转时,对目标页面来说,页面来源referrer就是当前页面
        this.setReferrer(this.getUrl());
        return router.pushUrl(options, mode);
      }   
      //返回上一页面或指定的页面
      //@param options
      back(options?: router.RouterOptions) {
        // 页面返回时,对目标页面来说,页面来源referrer就是当前页面
        this.setReferrer(this.getUrl());
        router.back(options);
      }
    ...
    }
    export default RouterManager;
    

    此外,由于RouterManager的创建,所以要在程序入口EntryAbility添加相关代码块。 具体代码块如下:

    // ets/entryability/EntryAbility.ts
    import RouterManager from '../model/RouterManager';
    import UIAbility from '[@ohos](/user/ohos).app.ability.UIAbility';
    import hilog from '[@ohos](/user/ohos).hilog';
    import window from '[@ohos](/user/ohos).window';
    ...
    ...
      onBackground() {
        hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground');
        const routeManagerInstance = RouterManager.getInstance();
        routeManagerInstance.setReferrer(undefined);
        ...
    ...    
    
  2. 获取页面的来源和传递参数:通过this.getReferrer可以直接获取页面来源referrer,referrer作为页面状态的一部分,也可以将在RouterState中调用getState()时可以获取到referrer。通过this.params可以获取发起跳转的页面往当前页传入的参数。(以第一页为例)

    注意:(本例效果呈现为预览器,因此打开第一页时此页的跳转来源为undefined,传来的参数也为undefined,且无法跳转回来源)

    具体代码块如下:

    // ets/pages/A.ets
    import RouterManager from '../model/RouterManager';
    
    [@Entry](/user/Entry)
    [@Component](/user/Component)
    struct A {
      private routeManagerInstance = RouterManager.getInstance();
      @State pageReferrer: string = '';
      @State params: Object = this.routeManagerInstance.getParams();
    
      onPageShow() {
        //调用RouterManager中的getReferrer()
        this.pageReferrer = this.routeManagerInstance.getReferrer();
        //调用RouterManager中的getParams()
        this.params = this.routeManagerInstance.getParams();
        console.log("页面栈长度:" + this.routeManagerInstance.getLength())
      }
      onBackPress() {
        this.routeManagerInstance.back();
        return true;
      }
      // 跳转回来源
      async routePage() {
        let options = {
          url: this.pageReferrer,
          params: {
            data: {
              text: 'B to pageReferrer data',
            }
          }
        }
        try {
          await this.routeManagerInstance.pushUrl(options);
        } catch (err) {
          console.info(` fail callback, code: ${err.code}, msg: ${err.msg}`)
        }
      }
    ...
    
  3. 页面的跳转:调用RouterManager中的pushUrl方法跳转到应用内的指定页面时,需要更新referrer。

    具体代码块如下:

    // ets/pages/A.ts
    //从A面跳转B面
    async routePageToB() {
      let options = {
        //跳转目标 
        url: 'pages/B',
        //传来的参数
        params: {
          data: {
            text: 'A to B data'
          }
        } 
      }
      try {
        await this.routeManagerInstance.pushUrl(options);
      } catch (err) {
        console.info(fail callback, code: ${err.code}, msg: ${err.msg})
      }
    }   
    //从A面跳转C面
    async routePageToC() {
      ...
    }
    //从A面跳转D面
    async routePageToD() {
      ...
    }
    ...
    Button({type: ButtonType.Normal, stateEffect: true }) {
      Text('跳转到B页')
      .fontSize(25)
      .fontWeight(FontWeight.Bold)
    }
    .borderRadius(8)
    .width(160)
    .height(60)
    .margin({ top: 20 })
    .backgroundColor('#C16E67')
    .onClick(() => {
      this.routePageToB()
    })
    
    Button({type: ButtonType.Normal, stateEffect: true }) {
      Text('跳转到C页')
      .fontSize(25)
      .fontWeight(FontWeight.Bold)
    }
    .borderRadius(8)
    .width(160)
    .height(60)
    .margin({ top: 20 })
    .backgroundColor('#C16E67')
    .onClick(() => {
      this.routePageToC()
    })
    
    Button({type: ButtonType.Normal, stateEffect: true }) {
      Text('跳转到D页')
      .fontSize(25)
      .fontWeight(FontWeight.Bold)
    }
    .borderRadius(8)
    .width(160)
    .height(60)
    .margin({ top: 20 })
    .backgroundColor('#C16E67')
    .onClick(() => {
      this.routePageToD()
    })
    
  4. 页面的返回:通过调用RouterManager中的back方法返回上一页面时,同时更新referrer。

    具体代码块如下:

    // ets/pages/A.ts
    ...
    Button() {
      Text('返回上一页')
      .fontSize(25)
      .fontWeight(FontWeight.Bold)
    }
    .height(60)
    .margin({ top: 20 })
    .backgroundColor('#C16E67')
    .onClick(() => {
      this.routeManagerInstance.back();
    })
    ...
    

更多关于HarmonyOS 鸿蒙Next开发案例 | 封装router方法造个轮子实现获取应用内部页面跳转来源功能的实战教程也可以访问 https://www.itying.com/category-93-b0.html

1 回复

更多关于HarmonyOS 鸿蒙Next开发案例 | 封装router方法造个轮子实现获取应用内部页面跳转来源功能的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


姓名:张三 职位:软件工程师 简介: 具有五年软件开发经验,熟悉Java、Python和C++。

回到顶部