【每日学点HarmonyOS Next知识】路由表、懒加载列表刷新UI、分屏适配、自定义弹框与软键盘间距、新路由支持横屏

68 阅读4分钟

1、HarmonyOS 系统路由表-首页无法监听到页面显示与隐藏?

资料:developer.huawei.com/consumer/cn…

场景:路由跳转如下:Index–>PageOne,从PageOne点击返回

代码如下:

@Entry
@Component
struct Index {
  pageStack : NavPathStack = new NavPathStack();

  build() {
    Navigation(this.pageStack){
    }.onAppear(() => {
      this.pageStack.pushPathByName("PageOne", null, false);
    })
    .hideNavBar(true)
  }

  onPageShow(): void {
    console.log('onPageShow')
  }

  onPageHide(): void {
    console.log('onPageHide')
  }
}

问题:从Index跳转到PageOne,onPageHide没有回调,从PageOne返回Index,onPageShow没有回调

请问怎么监听Index页面的显示与隐藏呢?(Index通过router跳转PageOne,能够看到正常页面回调)

可以使用NavPathStack配合navDestination属性进行页面路由,跳转时可以携带页面的信息,NavDestination有相关的 onShown 和 onHidden 方法。请参考如下:

NavPathStack文档:developer.huawei.com/consumer/cn…

onPageShow()方法仅在@Entry装饰的自定义组件生效,在Navigation包裹的NavDestination子页面返回时无法触发。可以使用如下方式监听返回主页面的显示隐藏,在回调方法中处理自有业务逻辑,具体说明如下:监听Navigation的onNavBarStateChange()事件,在回调中判断显示隐藏:参考文档: developer.huawei.com/consumer/cn…

2、HarmonyOS LazyForEach问题刷新UI问题?

首页List控件用LazyForEach去遍历生成不同条目的时候,键值生成用了业务id+index 生成。

如果第一个条目是轮播图,业务id为1 index为1 当运营后台为轮播图添加资源的时候 轮播图的业务id仍是1 只是轮播图多配了一张图 这个时候 我notify数组的时候 轮播控件是没有刷新的

请问怎么处理 键值生成的时候 添加随机数吗?

目前List的刷新策略是根据绑定的键值来的,键值对应了组件树,通过更新虚拟组件来刷新页面。由于增加图片的时候其键值并没有改变,没有触发刷新机制。增加随机数会导致每次加载都会刷新,影响性能。建议通过加入JSON.stringify(item)) + id + index来标识为建值

3、HarmonyOS 分屏适配。导航区能否根据TabBar支持多个`PageStack`用于维护页面栈?

 分屏适配。导航区能否根据TabBar支持多个`PageStack`用于维护页面栈。 效果等于xxx设备。每一个TabBar对应一个`PageStack`,切换TabBar时,可以还原对应Tab的页面栈。

参考结构如下,其中contentOne()和contentTwo()分别对应自己的页面栈

Tabs() {
  TabContent() {
    contentOne()
  }.tabBar('发现')
  TabContent() {
    contentTwo()
  }.tabBar('商城')
  .backgroundColor(Color.Pink)
}.barPosition(BarPosition.End)
.vertical(false) // 设置tab布局方向为水平方向
.barMode(BarMode.Fixed) // 所有子页签平分页签栏宽度,且页签栏不可滚动

4、HarmonyOS 自定义弹框和软键盘中有间距?

设置dialog在底部 dialog中有个textinput 现在打开弹框 弹框和软键盘中就会有间距 期望是弹框和软键盘贴和。尝试设置offset的dy也没有效果。

弹窗位置调整可以将customStyle设置为true并且给弹窗内部的column布局设置偏移.offset({ x: 0, y: xx})。

5、HarmonyOS 是否有一种方式能支持打开一个新路由时只在新路由中应用横屏效果,其他路由仍保持竖屏?

一个竖屏页点击切换到横屏时,是使用打开一个新路由的方式,目前的横屏实现方式,是在新路由页面中设置横屏 lastWindow.setPreferredOrientation(window.Orientation.LANDSCAPE),此时会导致一个问题,就是切换路由页面的过程中,原本竖屏的一级页面会被同时更改为横屏,原本横屏的二级页面会被同时修改为竖屏,并且在路由页面过渡的过程中这种更改是可见的,此情况被我司测试判断为缺陷。现考虑在跳转二级横屏页面时能否实现直接打开一个已经被置为横屏状态的路由容器,并且不影响一级竖屏页面的场景?

1、首先打开entry下面的module.json5文件,在abilities节点下添加一个orientation的属性:“orientation”: ‘unspecified’

2、第一个页面:

import { router } from '@kit.ArkUI';
@Entry
@Component
struct aboutScreen1 {
  @State message: string = '';

  build() {
    Column() {
      Text('首页,点我跳转')
        .fontSize(30)
        .textAlign(TextAlign.Center)
        .width('100%')
        .fontWeight(500)
        .height('100%')
        .onClick(() => {
          router.pushUrl({url: "pages/aboutScreen2" })
        })
    }
    .justifyContent(FlexAlign.Center)
    .width('100%')
    .backgroundColor(Color.White)
    .height('100%')
  }
}

3、第二个页面:

import { router, window } from '@kit.ArkUI';
import { BusinessError } from '@kit.BasicServicesKit';

@Entry
@Component
struct aboutScreen1 {
  @State message: string = '';

  aboutToAppear(): void {
    let orientation = window.Orientation.LANDSCAPE
    this.setScreenOrientation(orientation)
  }

  aboutToDisappear(): void {
    let orientation = window.Orientation.PORTRAIT
    this.setScreenOrientation(orientation)
  }

  setScreenOrientation(orientation: window.Orientation) {
    let windowClass: window.Window | undefined = undefined;
    try{
      let promise = window.getLastWindow(getContext())
      promise.then((data) => {
        windowClass = data
        windowClass.setPreferredOrientation(orientation)
      }).catch((err: BusinessError) => {
        console.error('getLastWindow error')
      })
    } catch (e) {
      console.error('setScreenOrientation error')
    }
  }

  build() {
    Column() {
      Text('我横屏啦')
        .fontSize(30)
        .textAlign(TextAlign.Center)
        .width('100%')
        .fontWeight(500)
        .height('50%')
    }
    .justifyContent(FlexAlign.Center)
    .width('100%')
    .backgroundColor(Color.White)
    .height('100%')
  }
}

##鸿蒙核心技术##鸿蒙开发工具##DevEco Studio## ##社交##