HarmonyOS 鸿蒙Next中如何自定义一个多功能标题栏?

HarmonyOS 鸿蒙Next中如何自定义一个多功能标题栏? 现在需要实现一个有左、右侧返回按钮的标题栏,标题内容居中显示,如何实现

3 回复

一、要实现一个自定义的标题栏组件,具有灵活的配置选项。它包含三个主要区域:

  1. 左侧区域:通常用于返回按钮
  2. 中间区域:用于显示标题文字和图标
  3. 右侧区域:用于显示操作按钮或菜单

二、实现流程

  1. 组件属性设计
    • 左侧参数设计
      • leftBackIcon: 返回图标资源
      • showLeftBack: 控制返回按钮显示/隐藏
    • 中间标题参数设计
      • title: 标题文字
      • titleIcon: 标题图标资源
      • titleIconPosition: 图标位置(左侧或右侧)
      • showTitleText: 控制标题文字显示/隐藏
      • showTitleIcon: 控制标题图标显示/隐藏
    • 右侧参数设计
      • rightText: 右侧文字内容
      • rightIcon: 右侧图标资源
      • showRightText: 控制右侧文字显示/隐藏
      • showRightIcon: 控制右侧图标显示/隐藏
      • showRightArea: 控制整个右侧区域显示/隐藏
  2. 事件回调设计
    • onBack: 返回按钮点击回调
    • onRightClick: 右侧区域点击回调
    • onTitleClick: 标题区域点击回调
  3. UI布局实现
    • 使用Row作为主容器
    • 左侧区域:条件渲染返回按钮
    • 中间区域:根据配置显示标题文字和图标
    • 右侧区域:条件渲染文字和图标组合
  4. 样式与交互
    • 设置固定高度(56px)
    • 设置背景颜色
    • 添加点击事件处理
    • 实现响应式布局

代码如下:

/**
 * @author J.query
 * @date 2025/3/21 8:51
 * @email j-query@foxmail.com
 * Description: 自定义标题栏
 */
import { setDarkColorMode, setLightColorMode } from "../common/ColorModeChangeFunctions";
import { common } from "@kit.AbilityKit";


@Component
export struct StandardTitleBar {
  // 左侧参数
  @Prop leftBackIcon: Resource = $r('app.media.left_back_white') // 返回图标
  @Prop showLeftBack: boolean = true // 控制返回按钮显隐
  private color: ResourceColor = $r('app.color.public_color_00428E');
  // 中间标题参数
  @Prop title: string = '' // 主标题文字
  @Prop titleIcon: Resource = $r('app.media.public_home_title_logo') // 标题图标
  @Prop titleIconPosition: 'left' | 'right' = 'left' // 图标位置
  @Prop showTitleText: boolean = true // 显示标题文字
  @Prop showTitleIcon: boolean = false // 显示标题图标
  // 右侧参数
  @Prop rightText: string = '更多' // 右侧文字
  @Prop rightIcon: Resource = $r('app.media.right_more_black') // 右侧图标
  @Prop showRightText: boolean = true // 显示右侧文字
  @Prop showRightIcon: boolean = true // 显示右侧图标
  @Prop showRightArea: boolean = true // 整体控制右侧区域
  @State currentAlign: FlexAlign = FlexAlign.Center
  // 事件回调(正确实现方式)
  private onBack: () => void = () => {
  }
  private onRightClick: () => void = () => {
  }
  private onTitleClick: () => void = () => {
  }

  aboutToAppear() {

  }

  build() {
    Row() {
      // 左侧返回按钮
      if (this.showLeftBack) {
        Image(this.leftBackIcon)
          .size({ height: 24 })
          .padding({ left: 10 })
          .onClick(() => this.onBack())
      }

      // 中间标题区域
      Row() {
        // 如果只有标题显示,则让标题完全居中
        if (this.showTitleText && !this.showTitleIcon) {
          Text(this.title)
            .fontColor($r('app.color.public_color_FFFFFFFF'))
            .fontSize(18)
            .textAlign(TextAlign.Center)// 文本居中
            .layoutWeight(1)
        } else {
          // 如果有图标或其他元素,保持原有布局
          if (this.showTitleIcon && this.titleIconPosition === 'left') {
            Image(this.titleIcon)
              .size({
                // width: '50%',
                height: '100%'
              })// .padding({ left: 5 })
              .objectFit(ImageFit.Contain)
          }
          Text(this.title)
            .fontColor($r('app.color.public_color_FFFFFFFF'))
            .fontSize(18)
            .textAlign(TextAlign.Center)// 文本居中
            .visibility(this.showTitleText ? Visibility.Visible : Visibility.None)
          if (this.showTitleIcon && this.titleIconPosition === 'right') {
            Image(this.titleIcon)
              .size({ width: 29, height: 20 })
            // .padding({ right: 5 })
          }
        }
      }
      .layoutWeight(1)
      .justifyContent(FlexAlign.Center) // 水平居中
      .onClick(() => this.onTitleClick())

      // 右侧组合区域
      if (this.showRightArea) {
        Row() {
          if (this.showRightText) {
            Text(this.rightText)
              .fontSize(14)
              .fontColor($r('app.color.public_color_FFFFFFFF'))
            // .padding({ right: 5 })
          }
          if (this.showRightIcon) {
            Image(this.rightIcon)
              .size({ width: 24, height: 24 })
            // .padding({ right: 5 })

          }
        }
        .padding({ right: 10 })
        .justifyContent(FlexAlign.Center)
        .onClick(() => this.onRightClick())
      }
    }
    .width('100%')
    .height(56)
    .backgroundColor(this.color)
  }
}

三、使用方法

  1. 基础用法
StandardTitleBar({
  title: "标题"
})
StandardTitleBar({
  title: this.simpleTitle,
  onBack: () => {
    console.log('点击了返回按钮')
    // 实际应用中可以使用 router.back() 返回上一页
  },
  onTitleClick: () => {
    console.log('点击了标题')
  },
  onRightClick: () => {
    console.log('点击了右侧按钮')
  }
})
.margin({ bottom: 20 })
  1. 完全自定义配置
StandardTitleBar({
  title: this.iconTitle,
  showTitleIcon: this.showIcon,
  titleIcon: $r('app.media.public_home_title_logo'),
  titleIconPosition: 'left',
  onBack: () => {
    console.log('点击了返回按钮')
  },
  onTitleClick: () => {
    // 点击标题切换图标显示状态
    this.showIcon = !this.showIcon
    console.log('点击了带图标标题')
  },
  onRightClick: () => {
    console.log('点击了右侧按钮')
  }
})
.margin({ bottom: 20 })

更多关于HarmonyOS 鸿蒙Next中如何自定义一个多功能标题栏?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS Next中,自定义多功能标题栏主要通过ArkUI的Navigation组件实现。开发者可使用Navigationtitle属性设置标题,并通过toolbar属性添加自定义操作按钮。例如,在toolbar中嵌套Row容器,结合ButtonImage组件实现搜索、菜单等功能。布局结构需在Page页面的build()方法内定义,利用@Entry@Component装饰器构建。样式可通过属性方法(如.width().fontSize())调整。

在HarmonyOS Next中,可以通过自定义CustomComponent来实现多功能标题栏。以下是核心实现步骤:

  1. 创建自定义组件

    • 使用[@Component](/user/Component)装饰器定义新组件,例如CustomTitleBar
    • 在布局中通过Row容器横向排列,使用Blank组件或Flex权重实现左右按钮与标题的定位。
  2. 布局结构示例

    [@Component](/user/Component)
    struct CustomTitleBar {
      build() {
        Row() {
          // 左侧返回按钮
          Image($r('app.media.back'))
            .onClick(() => {
              // 处理返回逻辑
            })
          
          // 中间标题(使用Blank填充左右空间)
          Blank()
          Text('标题内容')
            .fontSize(18)
          Blank()
          
          // 右侧按钮
          Image($r('app.media.more'))
            .onClick(() => {
              // 处理右侧功能
            })
        }
        .width('100%')
        .padding(10)
      }
    }
    
  3. 参数化配置

    • 通过@Prop@Link装饰器接收外部传入的标题文本、按钮图标及事件回调,提高组件复用性。
  4. 使用组件

    • 在页面中直接引用CustomTitleBar,并通过属性传递参数。

此方案通过ArkUI的声明式语法实现灵活布局,同时保持代码简洁性和可维护性。

回到顶部