# 9.3:自定义标题栏(TitleBar)

标题栏在移动端开发中是一个很常用的控件,带有标题栏的页面一般都是分成两部分,上边是标题栏,下边是页面内容,而标题栏的样式一般都是左边是一个返回键,中间是标题,右边是菜单,如下所示:

9_3

本节笔者简单实现一个标题栏控件 TitleBar ,向读者演示一下如何定义一个富功能的组件以及该组件的事件传递和参数设置。

# 9.3.1:定义标题栏TitleBar

根据样例图,标题栏分成三部分:左边是返回键,中间是标题,右边是菜单按钮,为了简单实现,笔者直接使用 Flex 组件把它在主轴方向上均分成 3 份,简单代码如下所示:

@Component export struct TitleBar {
  build() {
    Flex() {
      Stack({alignContent: Alignment.Start}) {  // 返回键左对齐
        Image($r("app.media.icon_back"))
          .width(35)
          .height(55)
          .objectFit(ImageFit.Contain)
          .padding(4)
          .margin({left: 10})
      }
      .layoutWeight(1)                          // 使用权重属性均分父布局

      Stack({alignContent: Alignment.Center}) { // 标题居中对齐
        Text('标题')
          .fontSize(25)
          .fontColor(Color.White)
      }
      .layoutWeight(1)                          // 使用权重属性均分父布局

      Stack({alignContent: Alignment.End}) {    // 菜单右对齐
        Image($r("app.media.icon_menu"))
          .width(35)
          .height(55)
          .objectFit(ImageFit.Contain)
          .margin({right: 10})
      }
      .layoutWeight(1)                          // 使用权重属性均分父布局
    }
    .width('100%')
    .height(55)
    .backgroundColor('#19c8ff')
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

TitleBar 定义完后,运行结果如下所示:

9_3_1_1

目前 TitleBar 组件只是一个静态控件,还不能相应返回事件以及更改标题以及图标等,接下我们来定义 TitleBar 的属性 TitleBarAttribute ,实现 UI 设置和事件响应的功能。

# 9.3.2:定义标题栏属性

根据样例,标题栏允许设置的属性包括:标题栏的高度和背景色;返回键的图片设置和事件响应,标题文本,大小,颜色和事件等,菜单键的样式及事件。 TitleBarAttribute 定义如下:

class TitleBarAttribute {
  // 返回键属性设置
  public backShow: boolean = false; // 是否显示返回键
  public backCallback: () => void;  // 点击返回键的事件回调

  // 标题属性设置
  public title: string = "";        // 设置标题文本

  // 菜单属性设置
  public menuShow: boolean = false; // 时候显示菜单
  public menuCallback: () => void;  // 点击菜单键的事件回调
}
1
2
3
4
5
6
7
8
9
10
11
12

TitleBarAttribute 简单属性定义了以上 5 个属性供调用者设置。接下来就是使用这些属性,然后根据不同的属性状态显示不同的样式。

# 9.3.3:使用标题栏属性

@Component export struct TitleBar {

  public titleBarAttribute: TitleBarAttribute; // 定义标题栏属性

  build() {
    Flex() {
      Stack({alignContent: Alignment.Start}) {
        if (this.titleBarAttribute && this.titleBarAttribute.backShow) { // 符合条件则显示
          Image($r("app.media.icon_back"))
            .width(30)
            .height(50)
            .objectFit(ImageFit.Contain)
            .margin({left: 10})
            .onClick(() => {
              this.titleBarAttribute?.backCallback.call(this) // 返回键点击事件回调
            })
        }
      }
      .layoutWeight(1)

      Stack({alignContent: Alignment.Center}) {
        if (this.titleBarAttribute && this.titleBarAttribute.title) { // 符合条件则显示
          Text(this.titleBarAttribute.title)
            .fontSize(25)
            .fontColor(Color.White)
        }
      }
      .layoutWeight(1)

      Stack({alignContent: Alignment.End}) {
        if (this.titleBarAttribute && this.titleBarAttribute.menuShow) { // 符合条件则显示
          Image($r("app.media.icon_menu"))
            .width(35)
            .height(55)
            .objectFit(ImageFit.Contain)
            .margin({right: 10})
            .onClick(() => {
              this.titleBarAttribute.menuCallback?.call(this); // 事件回调
            })
        }
      }
      .layoutWeight(1)
    }
    .width('100%')
    .height(55)
    .backgroundColor('#19c8ff')
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48

TitleBar 使用了 TitleBarAttribute 后,后续使用 TitleBar 时不传递任何参数,则标题栏只显示一个淡蓝色背景,效果如下所示:

9_3_3_1

# 9.3.4:使用标题栏TitleBar

  • 添加首页面如下:

    @Entry @Component struct ComponentTest {
    
      build() {
        Column() {
    
          TitleBar({titleBarAttribute: {
            title: "首页",
            menuShow: true,           // 显示菜单
            menuCallback: () => {     // 设置点击回调
              AlertDialog.show({      // 弹出对话框
                message: '您点击了菜单',
                autoCancel: true
              });
            }
          }})
    
          Button({type: ButtonType.Normal}) {
            Text('Setting')
              .fontSize(18)
          }
          .width(140)
          .height(50)
          .margin(50)
          .backgroundColor('#aabbcc')
          .borderRadius(8)
          .onClick(() => {
            router.push({uri: "pages/test/setting"}) // 点击跳转设置页
          })
        }
        .width('100%')
        .height('100%')
      }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
  • 添加设置页面如下:

    @Entry @Component struct Setting {
      build() {
        Column() {
          TitleBar({titleBarAttribute: {
            backShow: true,       // 显示返回键
            backCallback: () => {							
              router.back()       // 点击返回上一页
            },
            title: "设置"          // 设置标题
          }})
        }
        .width('100%')
        .height('100%')
      }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

    运行结果如下图所示:

    9_3_4_1

# 9.3.5:小结

以上就是自定义标题栏的简单实现,笔者并没有把它的功能做的很丰富,样例只是向大家介绍自定义组件的用法,读者掌握此用法后,完全可以在此基础进行更丰富的功能扩展,比如允许设置标题栏的高度、颜色,标题文字的大小、颜色、字体以及菜单图片替换等样式。

(adsbygoogle = window.adsbygoogle || []).push({});
请作者喝杯咖啡

津公网安备 12011402001367号

津ICP备2020008934号-2