HarmonyOS 鸿蒙Next Navigation路由改造过程自定义导航栏空白问题
HarmonyOS 鸿蒙Next Navigation路由改造过程自定义导航栏空白问题
一 问题描述
项目页面路由由Router改造为Navigation、NavPathStack路由管理后,非首页设置hideToolBar为true,但是非首页内的自定义导航栏头一直是空白,自定义UI没有展示出来。
二 原因剖析
图 Router和Navgation路由结构对比图
项目Router路由时,如图1所示,每个页面单独创建LocalStorage实例,单个页面使用自己创建的LocalStorage实例,进行页面级别状态变量的存储,这种情况下,自定义导航栏数据模型的状态变量可以正常存储和UI的驱动刷新。
项目改造为Navigation路由后,如图2所示,首页页面使用Navition包裹,非首页页面需要NavDestination属性包裹,作为子页面的根容器,用于显示Navigation的内容区。进而由系统页面栈NavPathStack进行管理,除首页作为页面外,其他被NavDestination包裹的非首页部分,均由页面降为组件级别,所以非首页子组件的LocalStorage只能接受父组件首页(即第一个Index页面)通过@Entry传递来的LocalStorage实例,在Navigation路由管理的非首页的NavDestination子组件均接收父组件传递过来的LocalStorage对象,不可以单独创建LocalStorage对象,并且组件最多可以访问一个LocalStorage实例。
由于上述Router和Navigation两种路由在非首页页面使用LocalStorage对象的不同要求,导致Router路由下的页面自定义导航栏UI驱动刷新失效,需要改造为从首页Navgation页面传递LocalStorage对象,非首页页面的NavDestination子组件会自动接收父组件传递过来的LocalStorage对象,这样子页面级别的状态变量的存储就会恢复正常,所以自定义导航栏就会正常刷新。
三 解决方案
1 Index.ets文件
如上图代码所示,在Navigation包裹的首页Index页面,创建LocalStorage对象,传递给BCMWebContainer非首页子组件。
2 BCMWebContainer.ets文件
由于Index首页传递过来LocalStorage实例对象,BCMWebContainer组件的所有子组件实例将自动获得首页传递的LocalStorage实例的访问权限,这样@LocalStorageLink装饰的自定义组件的状态变量就会自动更新同步回LocalStorage,从而导航栏数据模型的变化就会联动UI的刷新。
附录 LocalStorage、Navigation
LocalStorage是ArkTS为构建页面级别状态变量提供存储的内存内“数据库”。
- 应用程序可以创建多个LocalStorage实例,LocalStorage实例可以在页面内共享,也可以通过GetShared接口,实现跨页面、UIAbility实例内共享。
- 组件树的根节点,即被@Entry装饰的@Component,可以被分配一个LocalStorage实例,此组件的所有子组件实例将自动获得对该LocalStorage实例的访问权限;
- 被@Component装饰的组件最多可以访问一个LocalStorage实例和AppStorage,未被@Entry装饰的组件不可被独立分配LocalStorage实例,只能接受父组件通过@Entry传递来的LocalStorage实例。一个LocalStorage实例在组件树上可以被分配给多个组件。
Navigation组件是路由导航的根视图容器,一般作为Page页面的根容器使用,其内部默认包含了标题栏、内容区和工具栏,其中内容区默认首页显示导航内容(Navigation的子组件)或非首页显示(NavDestination的子组件),首页和非首页通过路由进行切换。
针对HarmonyOS 鸿蒙Next在Navigation路由改造过程中出现的自定义导航栏空白问题,这通常是由于路由结构变化导致的页面级别状态变量存储和UI刷新机制受影响。
在Navigation路由下,非首页页面由NavDestination属性包裹,作为子页面的根容器,其LocalStorage实例由父组件(即首页)传递,而非单独创建。这导致非首页的自定义导航栏数据模型状态变量无法正常存储和刷新UI。
解决方案是,确保在首页的Navigation组件中创建LocalStorage对象,并通过@Entry传递给非首页的NavDestination子组件。这样,非首页的子组件实例将自动获得对首页传递的LocalStorage实例的访问权限,从而实现状态变量的正常存储和UI的刷新。
如果上述方法未能解决问题,可能是由于页面布局与安全区域设置不当导致。请检查并调整expandSafeArea属性,确保组件可以绘制到安全区域之外。同时,注意组件不应设置固定宽高(百分比除外),否则可能导致expandSafeArea属性无效。
如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html。