HarmonyOS鸿蒙Next中Navigation自定义标题栏不生效问题如何修改

HarmonyOS鸿蒙Next中Navigation自定义标题栏不生效问题如何修改

【问题现象】

使用Navigation时,自定义了一个标题栏布局,使用其中的title方法无效。如图:

点击放大

问题代码如下:

@Builder
customTitleBuilder() {
  Row() {
    Text(this.text)
  }
}

customTitle: NavigationCustomTitle = {
  builder: this.customTitleBuilder(),
  height: TitleHeight.MainOnly
}

build() {
  Navigation() {
    Column() {
      Text('首页')
        .fontSize(40)
    }
    .justifyContent(FlexAlign.Center)
    .width('100%')
    .height('100%')
  }
  .title(this.customTitle)
}

【背景知识】

Navigation是路由容器组件,一般作为首页的根容器。其内部默认包含了标题栏、内容区和工具栏。其中内容区默认首页显示导航内容,标题栏和工具栏均支持传入自定义样式。

【定位思路】

使用ArkUI Inspector查看应用布局,发现TitleBar不可见,标题栏未创建。

点击放大

查看title传入参数类型,其中NavigationCustomTitle 和CustomBuilder这两种类型均支持自定义标题栏样式,而代码中使用的正是NavigationCustomTitle 类型。因此,首先需要排查该类型对象构造是否正确。

// Navigation的title方法声明
title(value: ResourceStr | CustomBuilder | NavigationCommonTitle | NavigationCustomTitle, options?: NavigationTitleOptions)

经过排查,是由于自定义标题的方法在传入时,没有绑定当前上下文。在执行时,this指向了NavigationCustomTitle对象,找不到相应的方法,因而无法渲染绘制标题栏。

【解决方案】

方案一:NavigationCustomTitle里builder传入方法需要bind(this)

代码示例如下:

customTitle: NavigationCustomTitle = {
  builder: this.customTitleBuilder.bind(this), // 绑定this
  height: TitleHeight.MainOnly
}

方案二:title方法直接传入自定义布局的方法

代码示例如下:

.title(this.customTitleBuilder())

修改后效果如图:

点击放大

【总结】

  • JS函数中的this不是在函数声明时定义的,而是在运行时定义的,谁调用这个函数,this就指向谁。js的bind(this)会创建一个新函数,并将该方法与当前的上下文绑定,因此在执行时能找到相应的方法,并成功渲染出标题栏。
  • 如果直接传this.customTitleBuilder(),在执行过程中,this会指向customTitle这个对象。由于该对象中不存在customTitleBuilder方法,因此无法渲染出标题栏。
  • title直接传this.customTitleBuilder时,当前的this依旧指向当前上下文,this.customTitleBuilder指向函数本身,因此能执行该方法,并渲染出标题栏。

更多关于HarmonyOS鸿蒙Next中Navigation自定义标题栏不生效问题如何修改的实战教程也可以访问 https://www.itying.com/category-93-b0.html

1 回复

更多关于HarmonyOS鸿蒙Next中Navigation自定义标题栏不生效问题如何修改的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS鸿蒙Next中,自定义标题栏不生效的原因是this指向错误。解决方案如下:

  1. 绑定上下文:在NavigationCustomTitlebuilder中,使用bind(this)绑定当前上下文。

    customTitle: NavigationCustomTitle = {
      builder: this.customTitleBuilder.bind(this), // 绑定this
      height: TitleHeight.MainOnly
    }
    
  2. 直接传入方法:在title方法中直接传入自定义布局的方法。

    .title(this.customTitleBuilder())
    

这两种方法均可解决自定义标题栏不生效的问题。

回到顶部