Navigation可以作为路由组件来使用
1、可以实现雷同Android startActivityForResult的功能。
2、可以实现页面生命周期函数的回调监听
一、Navigation 根节点监听页面的显示和隐蔽
可以通过Navigation onNavBarStateChange函数监听当前页面(Navigation根节点)的显示和隐蔽,通过@State注解的字段传递给TabContent组件,让TabContent可以观察页面的显示和隐蔽状态。
- @Entry
- @Component
- struct Index {
- @Provide indexPathStack: NavPathStack = new NavPathStack()
- //当前选中的下标
- @State currentIndex: number = 0
- private tabsController: TabsController = new TabsController();
- @State onPageResume: boolean = false
- aboutToAppear(): void {
- console.info('Index aboutToAppear')
- }
- /**
- * 应用前后台显示
- */
- onPageShow(): void {
- console.info('Index onPageShow')
- }
- /**
- * 应用前后台隐藏
- */
- onPageHide(): void {
- console.info('Index onPageHide')
- }
- @Builder
- tabBarBuilder(title: string, targetIndex: number, selectIcon: Resource, unSelectIcon: Resource) {
- ......
- }
- build() {
- Navigation(this.indexPathStack) {
- Tabs({ barPosition: BarPosition.End, controller: this.tabsController }) {
- TabContent() {
- Home()
- }
- .tabBar(this.tabBarBuilder('首页', 0, $r('app.media.ic_home_on'), $r('app.media.ic_home_off')))
- TabContent() {
- Mine({ onPageResume: this.onPageResume })
- }.tabBar(this.tabBarBuilder('我的', 1, $r('app.media.ic_mine_on'), $r('app.media.ic_mine_off')))
- }
- .vertical(false)
- .divider({ strokeWidth: 0.5, color: '#0D182431' })
- .scrollable(false)
- .backgroundColor('#F1F3F5')
- }
- .mode(NavigationMode.Stack)
- .hideTitleBar(true)
- // .hideToolBar(true)
- .backgroundColor("#FFFFFF")
- .onNavBarStateChange((isVisible: boolean)=>{
- //Navigation组件,根节点如何监听隐藏与展示,监听页面占中的显示和隐藏,上个页面返回的时候会触发,https://www.wzhi.top/?id=25
- console.info(`onNavBarStateChange isVisible=${isVisible}`)
- this.onPageResume = isVisible
- })
- }
- }
复制代码 二、Navigation子页面NavDestination实现页面显示隐蔽的监听
Navigation的子页面必要获得栈变量并进行栈的操作,Index.ets的栈变量
- @Consume indexPathStack: NavPathStack;
复制代码 子页面的实现:
- @Preview
- @Component
- export struct Mine {
- @State isLogin: boolean = false
- @State userInfo: UserInfo = {
- avatar: $r('app.media.ic_default_avatar'),
- nickname: '未登录'
- }
- @Consume indexPathStack: NavPathStack;
- isFirstShow: boolean = true;
- @Prop @Watch('onPageResumeChange') onPageResume: boolean
- /**
- * 监听页面课件状态,onPageResume 由Index.ets页面传递过来
- */
- onPageResumeChange() {
- console.info(`Mine onPageResumeChange this.onPageResume=${this.onPageResume} isFirstShow=${this.isFirstShow}`)
- if (this.isFirstShow) {
- this.isFirstShow = false
- return
- }
- if (this.onPageResume) {
- this.getLocalUserInfo()
- }
- }
- /**
- * 在创建自定义组件后,执行其build()函数之前执行(NavDestination创建之前),允许在该方法中改变状态变量,更改将在后续执行build()函数中生效。
- */
- aboutToAppear(): void {
- console.info('mine aboutToAppear')
- this.getLocalUserInfo()
- }
- getLocalUserInfo() {
- ......
- }
- build() {
- NavDestination() {
- Column() {
- ......
- }
- .width('100%')
- .height('100%')
- .backgroundColor('#F5F5F5')
- }
- .mode(NavDestinationMode.STANDARD)
- .hideTitleBar(true)
- .onShown(() => {
- console.info('Mine onShown')
- }).onHidden(() => {
- console.info('Mine onHidden')
- })
- }
- @Builder
- MenuItem(
- icon: Resource,
- title: string,
- onClick: () => void
- ) {
- ......
- }
- }
复制代码 可以通过NavDestination的方法.onShown/onHidden监听页面的显示和隐蔽,不过NavDestination是Navigation的跟节点,这个方法就不生效了,比方我再Index.ets中使用了Navigation 嵌套Tabs,TabContent中使用了NavDestination,使用onShown/onHidden就无法被回调,必要在Navigation中使用onNavBarStateChange来监听,把状态传递给TabContent实现页面显示隐蔽的监听。
三、Navigation通过NavPathStack实现页面路由(页面跳转)
1、Navigation实现页面路由,其实是通过NavPathStack的方法来实现的。
可以看到Navigation中传入了参数indexPathStack,类型是NavPathStack,在往下看,是子页面NavDestination接收indexPathStack这个变量来进行页面路由
- @Entry
- @Component
- struct Index {
- @Provide indexPathStack: NavPathStack = new NavPathStack()
- @Builder
- tabBarBuilder(title: string, targetIndex: number, selectIcon: Resource, unSelectIcon: Resource) {
- ......
- }
- build() {
- Navigation(this.indexPathStack) {
- Tabs({ barPosition: BarPosition.End, controller: this.tabsController }) {
- ......
- }
- .vertical(false)
- .divider({ strokeWidth: 0.5, color: '#0D182431' })
- .scrollable(false)
- .backgroundColor('#F1F3F5')
- }
- .mode(NavigationMode.Stack)
- .hideTitleBar(true)
- // .hideToolBar(true)
- .backgroundColor("#FFFFFF")
- .onNavBarStateChange((isVisible: boolean)=>{
- //Navigation组件,根节点如何监听隐藏与展示,监听页面占中的显示和隐藏,上个页面返回的时候会触发,https://www.wzhi.top/?id=25
- console.info(`onNavBarStateChange isVisible=${isVisible}`)
- this.onPageResume = isVisible
- })
- }
- }
复制代码 2、NavDestination接收indexPathStack这个变量来进行页面路
由NavDestination接收indexPathStack这个变量来进行页面路由。
通过 @Consume indexPathStack: NavPathStack 来获取Navigation传递过来的路由栈变量,在onClick中调用this.indexPathStack.pushPathByName 实现页面的跳转。当然参数中的name必要进行配置,接着往下看。
- @Preview
- @Component
- export struct Mine {
- @Consume indexPathStack: NavPathStack;
- getLocalUserInfo() {
- ......
- }
- build() {
- NavDestination() {
- Column() {
- // 顶部用户信息区域
- Row() {
- Image(this.userInfo.avatar)
- .width(80)
- .height(80)
- .borderRadius(40)
- .margin({ right: 20 })
- .onClick(() => {
- if (!this.isLogin) {
- console.info('跳转到登录页面')
- this.indexPathStack.pushPathByName('PageLogin', null, true)
- }
- })
- ......
- }
- .width('100%')
- .padding(20)
- .backgroundColor('#FFFFFF')
-
- }
- .margin({ top: 12 })
- .backgroundColor('#FFFFFF')
- }
- .width('100%')
- .height('100%')
- .backgroundColor('#F5F5F5')
- }
- .mode(NavDestinationMode.STANDARD)
- .hideTitleBar(true)
- .onShown(() => {
- console.info('Mine onShown')
- }).onHidden(() => {
- console.info('Mine onHidden')
- })
- }
- @Builder
- MenuItem(
- icon: Resource,
- title: string,
- onClick: () => void
- ) {
- ......
- }
- }
复制代码 3、在src/main/resources/base/profile目录下面创建route_map.json文件,进行路由页面的配置
- {
- "routerMap": [
- {
- "name": "PageLogin",//自定义组件的名称
- "pageSourceFile": "src/main/ets/components/login.ets",//自定义组件所在的.ets文件的路径
- "buildFunction": "PageLoginBuilder",//路由目标页面需要实现这个方法,调用PageLogin(),才能实现最终的路径
- "data": {
- "description" : "this is Page Login"//当前路由的描述
- }
- },
- {
- "name": "RegisterPage",
- "pageSourceFile": "src/main/ets/components/register.ets",
- "buildFunction": "PageRegisterBuilder",
- "data": {
- "description" : "this is Page register"
- }
- },
- {
- "name": "SettingPage",
- "pageSourceFile": "src/main/ets/components/setting.ets",
- "buildFunction": "PageSettingBuilder",
- "data": {
- "description" : "this is Page setting"
- }
- }
- ]
- }
复制代码 4、路由目的页面实现,以登录页面为例
- // 跳转页面入口函数,路由配置中配置的函数名称
- @Builder
- export function PageLoginBuilder() {
- LoginPage()
- }
- @Component
- struct LoginPage {
- @State username: string = ''
- @State password: string = ''
- @State isLoading: boolean = false
- @Consume indexPathStack: NavPathStack
- build() {
- NavDestination() {
- Column() {
-
- }
- .width('100%')
- .height('100%')
- .backgroundColor('#FFFFFF')
- }
- .hideTitleBar(true)
- .onShown( ()=>{//页面显示的监听
- console.info('login onShow')
- })
- .onHidden(()=>{//页面隐藏的监听
- console.info('login onHidden')
- })
- }
- private handleLogin() {
- ......
- }
- }
复制代码
完整代码已经上传到gitee:WanHarmony: wanAndroid api 鸿蒙应用
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |