HarmonyOS 鸿蒙Next关于Navigation的疑惑

发布于 1周前 作者 yuanlaile 来自 鸿蒙OS

HarmonyOS 鸿蒙Next关于Navigation的疑惑
<markdown _ngcontent-bgf-c237="" class="markdownPreContainer">

在官方文档中的描述

Navigation是路由容器组件,一般作为首页的根容器

这里的首页根容器是指的用Entry修饰的页面呢,还是类似于底部导航切换子页面的模式,然后 Navigation又具有router的功能,那么也就是支持 Page To Page的模式,例如一个列表页跳转到详情页.

现在我有两个页面,一个SplashPage,一个MainPage,其中MainPage具有底部导航切换功能,这种样式基本都存在

在使用页面路由router的时候,SplashPage,MainPage都需要使用 [@Entry](/user/Entry),然后通过使用

router.replaceUrl({url:'pages/main/MainPage'})

来进行跳转,当跳转到MainPage后,按下返回键是直接退出应用了. 那么既然Navigation也支持router的功能,那么整体下可以只需要一个Navigation,然后各个页面则使用NavDestination来包裹,在这种情况下,大概只需要一个 Entry 修饰的主入口, 然后对SplashPage,MainPage进行修改,新增一个使用Entry修饰的Index页面,其中build中使用Navigation包裹

[@Entry](/user/Entry)
[@Component](/user/Component)
struct Index {
  private navPathStack = new NavPathStack();

aboutToAppear(): void { AppStorage.setOrCreate(“NavPathStack”, this.navPathStack); }

build() { Navigation(this.navPathStack) { SplashPageBuilder(); }.mode(NavigationMode.Stack) } } <button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 4px; right: 8px; font-size: 14px;">复制</button>

接着修改SplashPage

[@Builder](/user/Builder)
export function SplashPageBuilder() {
  SplashPage()
}
[@Component](/user/Component)
struct SplashPage{
  private navPathStack = AppStorage.get<NavPathStack>("NavPathStack");
    build(){
        NavDestination(){
            ......
        }
    }
}
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 4px; right: 8px; font-size: 14px;">复制</button>

MainPage

[@Builder](/user/Builder)
export function MainPageBuilder() {
  MainPage()
}
[@Component](/user/Component)
struct MainPage{
  private navPathStack = AppStorage.get<NavPathStack>("NavPathStack");
    build(){
        NavDestination(){
            ......
        }
    }
}
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 4px; right: 8px; font-size: 14px;">复制</button>

路由表:

{
  "routerMap": [
    {
      "name": "splash",
      "pageSourceFile": "src/main/ets/pages/splash/SplashPage.ets",
      "buildFunction": "SplashPageBuilder"
    },
    {
      "name": "main",
      "pageSourceFile": "src/main/ets/pages/main/MainPage.ets",
      "buildFunction": "MainPageBuilder"
    }
  ]
}
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 4px; right: 8px; font-size: 14px;">复制</button>

最后SplashPage添加一个跳转MainPage的事件

this.navPathStack.pushPathByName("main", null);
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 4px; right: 8px; font-size: 14px;">复制</button>

通过在模拟器中测试,正常跳转,但是一般从Splash 到 Main,肯定不会用push来跳转,而是用replace去跳转,问题来了,当我使用

navPathStack.replacePathByName("main",null);
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 4px; right: 8px; font-size: 14px;">复制</button>

跳转是正常的,此时按下返回键时,竟然回到了SplashPage,难道不是应该就直接退出应用吗 我现在相当疑惑,希望有大佬能够解答一下

</markdown>

关于HarmonyOS 鸿蒙Next关于Navigation的疑惑的问题,您也可以访问:https://www.itying.com/category-93-b0.html 联系官网客服。
10 回复
他这个replace是将当前页进行替换,你的这个栈原本是 index splash ,你用replace将splash变成了main,所以栈里面是index main,然后你按返回键 就会回到index, 而index的build会直接执行splash的构造函数,所以你的现象是回到了splash,但实际上路径是main-> index -> splash。我的建议是你可以把splash当做第一屏,然后replace出去就好了

而且还有一个问题,如下代码的效果图,在entry中直接套用NavDestination页面会有一个返回按钮,点击无效!

但是如果按照楼主的写法就没有这个返回按钮,这有啥区别,这Navigation理解不上去了~

cke_441.png

cke_3668.png

开屏页和主页面这种跳转还是用router吧

我把它index页添加如下跳转

this.navPathStack?.replacePathByName("splash", null)<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>

SplashPage页添加如下跳转

this.navPathStack?.replacePathByName("main", null)<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>

再点击返回,从main直接返回到了index页,Splash页确实被顶出去了,

好像navigation这个页面不会被销毁

很喜欢HarmonyOS的简洁设计风格,让人一眼就能找到需要的功能。

看到楼主上面的代码中有这么一行

AppStorage.setOrCreate("NavPathStack", this.navPathStack);

请问楼主,这是注册全局路由表吗?

是个不错的demo 分析例子,Navigation 子页面都用
NavDestination 包裹,也就失去Page页面的功能和函数回调。。。。
    Navigation(this.rootNavigation) {

      ...

    }

    .hideNavBar(true)

你好楼主,这个问题我刚刚解决具体解决方法如下:

cke_602.png

在 main页面返回时触发这个onBackPressed方法,onBackPressed返回 true 时不会返回到上一页,并且模拟器不会退出应用,但是真机不知道会不会退出应用,没有真机试不了,楼主如果有条件的话,请将实验的结果回复一下,大家一起进步

感觉这样也不太合理,使用replacePathByName时上一页面按理说应该直接销毁 不应该在MainPage里面拦截呀

楼主您好,该问题需要demo代码进行分析,建议通过在线提单提交问题。

支持 - 在线提单 - 华为开发者联盟 (huawei.com)

回到顶部