纯血鸿蒙APP实战开发——Navigation实现多设备适配案例

介绍

在应用开发时,一个应用需要适配多终端的设备,使用Navigationmode属性来实现一套代码,多终端适配。

效果图预览

使用说明

  1. 将程序运行在折叠屏手机或者平板上观看适配效果。

实现思路

本例涉及的关键特性和实现方案如下:

1.分屏的使用

首先介绍的是本案例的关键特性Navigationmode属性,原先采用的是NavigationMode.Stack,导航栏与内容区独立显示,相当于两个页面。
现在采用当设备宽度>=600vp时,采用Split模式显示;设备宽度<600vp时,采用Stack模式显示。通过display.isFoldable()判断是否设备可折叠,如果可折叠
通过display.on(‘foldStatusChange’)来开启折叠设备折叠状态变化的监听,折叠时是Stack模式,半折叠和完全展开时采用Split模式。


if (display.isFoldable()) {
   
   this.regDisplayListener();
} else {
   
   if (this.screenW >= this.DEVICESIZE) {
   
     this.navigationMode = NavigationMode.Split;
   } else {
   
     this.navigationMode = NavigationMode.Stack;
   }
}

/**
* 注册屏幕状态监听
* @returns {void}
*/
regDisplayListener(): void {
   
   this.changeNavigationMode(display.getFoldStatus());
   display.on('foldStatusChange', async (curFoldStatus: display.FoldStatus) => {
   
      // 同一个状态重复触发不做处理
      if (this.curFoldStatus === curFoldStatus) {
   
         return;
      }
      // 缓存当前折叠状态
      this.curFoldStatus = curFoldStatus;
      this.changeNavigationMode(this.curFoldStatus);
   })
}

// 更改NavigationMode
changeNavigationMode(status: number): void {
   
   if (status === display.FoldStatus.FOLD_STATUS_FOLDED) {
   
      this.navigationMode = NavigationMode.Stack;
   } else {
   
      this.navigationMode = NavigationMode.Split;
   }
}
...
Navigation(this.pageStack) {
    ... }
   .backgroundColor($r('app.color.main_background_color'))
   .hideTitleBar(true)
   .navBarWidth($r('app.string.entry_half_size'))
   .hideNavBar(this.isFullScreen)
   .navDestination(this.pageMap)
   .mode(this.navigationMode)
2.模块全屏的使用以及Bug解决

EntryViewNavigation中设置hideNavBar,其值设置为由@Provide装饰器装饰过的变量,默认值为false,作用是为了适配需要全屏的模块。
在对应模块的实现文件声明由@Consume装饰器装饰过的变量,更改变量的值就可以实现与后代组件双向同步的通信,从而实时确定是否需要
hideNavBar

 // EntryView.ets
 ...
 @Provide('isFullScreen') isFullScreen: boolean = false;
 ...
 Navigation(this.pageStack) {
    ... }
   .backgroundColor($r('app.color.main_background_color'))
   .hideTitleBar(true)
   .navBarWidth($r('app.string.entry_half_size'))
   .hideNavBar(this.isFullScreen)
   .navDestination(this.pageMap)
   .mode(this.navigationMode)
 ...
 
 // FunctionalScenes.ets
  if (this.isNeedClear) {
   
     DynamicsRouter.clear();
  }
  if (this.listData !== undefined) {
   
     // 点击瀑布流Item时,根据点击的模块信息,将页面放入路由栈
     DynamicsRouter.push(this.listData

你可能感兴趣的:(鸿蒙开发,harmonyOS,移动开发,harmonyos,华为,界面布局,移动开发,鸿蒙开发,ui)