HarmonyOS鸿蒙Next中如何解决Menu组件在数据为空时依旧显示的问题

HarmonyOS鸿蒙Next中如何解决Menu组件在数据为空时依旧显示的问题

【问题现象】

点击放大

如上图所示,在Menu组件内数据为空时,点击蓝色的菜单按钮,左下角依旧弹出一个白色圆点。本身是符合组件逻辑,展示组件内容为空。但是,若开发设计为当菜单为空时,不展示菜单,此时不符合要求。

【背景知识】

当前Menu组件作为一个绑定交互组件,被应用在各种地方,例如历史记录、账号等。目前Menu当其中的信息为空时,会展示一个空白的交互框提示用户无信息,但若应用设计方面决定是不展示,则可按照如下方式实现。

【定位思路】

使用bindMenu。让Menu为空时不显示可以通过如下三方面入手(其他组件也可类似分析)

1 查看组件自身是否有属性可以控制(Menu自身属性)

经查看官方文档,Menu无对应属性控制是否显示

2 让组件隐身(Menu组件本身)

通过显隐控制可知,在Menu数据为空时,设置Menu组件visibility属性为None即可。注意此处不可设置为Hidden。此方法隐藏的原因是绑定的Builder组件为空没有内容可显示,因此点击无显示。参与布局会让Builder内由内容可显示,无法隐藏,因此只能使用None无法使用Hidden。同理可使用if让Builder内组件不参与组件树构建,不生成内容。

名称 描述
Hidden 隐藏,但参与布局进行占位。
Visible 显示。
None 隐藏,但不参与布局,不进行占位。

3 组件不触发Menu显示事件(被绑定Menu的组件)

3.1 禁用控制

通过禁用控制可知,设置enabled为false即可阻止交互事件,因此设置绑定Menu事件的组件的enabled为false。

注意

此时该组件进入不可交互状态,不会响应点击事件触摸事件拖拽事件按键事件焦点事件鼠标事件。同时组件UI会发生变化。

3.2 触摸测试控制

通过触摸测试控制可知,将组件组件测试拦截hitTestBehavior设置为HitTestMode.None,即可使当前组件不相应触摸事件,同时不影响同位置不同层级组件的点击相应。

【解决方案】

1 让组件隐身

@Entry
@Component
struct Index {

  @State visibility_param: Visibility = Visibility.Visible
  @Builder
  MyMenu() {
    Menu()
    .visibility(this.visibility_param)
  }
  build() {
    Column({ space: 30 }) {
      Button('菜单')
        .bindMenu(this.MyMenu)
      Button('Visibility = ' + this.visibility_param)
        .onClick(() => {
          this.visibility_param += 1
          if (this.visibility_param == 3) {
            this.visibility_param = 0
          }
        })
    }
    .width('100%')
    .height('100%')
    .alignItems(HorizontalAlign.Center)
    .backgroundColor(Color.Grey)
  }
}

以下对应三种效果图

  • Visibility = Visible

点击放大

  • Visibility = Hidden

点击放大

  • Visibility = None

点击放大

2 禁用控制

@Entry
@Component
struct menu {

  @State enabled_param: boolean = true
  @Builder
  MyMenu() {
    Menu()
  }
  build() {
    Column({ space: 30 }) {
      Button('菜单')
        .bindMenu(this.MyMenu)
        .enabled(this.enabled_param)
      Button('Enable = ' + this.enabled_param )
        .onClick(() => {
          this.enabled_param = !this.enabled_param
        })
    }
    .width('100%')
    .height('100%')
    .alignItems(HorizontalAlign.Center)
    .backgroundColor(Color.Grey)
  }
}

以下是两种效果图

  • Enable = true

点击放大

  • Enable = false

点击放大

3 触摸测试控制

@Entry
@Component
struct menu {

  @State hitTestBehavior_param: HitTestMode = HitTestMode.Default
  @Builder
  MyMenu() {
    Menu()
  }
  build() {
    Column({ space: 30 }) {
      Blank()
        .height(100)
      Button('菜单')
        .bindMenu(this.MyMenu)
        .hitTestBehavior(this.hitTestBehavior_param)
      Button('HitTestMode = ' + this.hitTestBehavior_param)
        .onClick(() => {
          if (this.hitTestBehavior_param == HitTestMode.Default) {
            this.hitTestBehavior_param = HitTestMode.None
          } else {
            this.hitTestBehavior_param = HitTestMode.Default
          }
        })
    }
    .width('100%')
    .height('100%')
    .alignItems(HorizontalAlign.Center)
    .backgroundColor(Color.Grey)
  }
}

以下是两种效果图

  • HitTestMode = Default

点击放大

  • HitTestMode = None

点击放大

【总结】

对于通过交互显示组件的问题,可以按照定位思路从三方面出发,首先查看显示组件自身是否有单独属性可以处理,其次就是使用通用的属性Visibility来处理显隐问题,最后可屏蔽交互事件,防止触发组件显示。


更多关于HarmonyOS鸿蒙Next中如何解决Menu组件在数据为空时依旧显示的问题的实战教程也可以访问 https://www.itying.com/category-93-b0.html

1 回复

更多关于HarmonyOS鸿蒙Next中如何解决Menu组件在数据为空时依旧显示的问题的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS鸿蒙Next中,当Menu组件数据为空时,可以通过以下方法实现不显示Menu:

1. 让组件隐身

设置Menu组件的visibility属性为None,使其不参与布局且不显示。

示例代码:

@Entry
@Component
struct Index {
    @State visibility_param: Visibility = Visibility.Visible
    @Builder
    MyMenu() {
        Menu()
        .visibility(this.visibility_param)
    }
    build() {
        Column({ space: 30 }) {
            Button('菜单')
                .bindMenu(this.MyMenu)
            Button('Visibility = ' + this.visibility_param)
                .onClick(() => {
                    this.visibility_param += 1
                    if (this.visibility_param == 3) {
                        this.visibility_param = 0
                    }
                })
        }
        .width('100%')
        .height('100%')
        .alignItems(HorizontalAlign.Center)
        .backgroundColor(Color.Grey)
    }
}

2. 禁用控制

设置绑定Menu事件的组件的enabled属性为false,阻止交互事件触发。

示例代码:

@Entry
@Component
struct menu {
    @State enabled_param: boolean = true
    @Builder
    MyMenu() {
        Menu()
    }
    build() {
        Column({ space: 30 }) {
            Button('菜单')
                .bindMenu(this.MyMenu)
                .enabled(this.enabled_param)
            Button('Enable = ' + this.enabled_param )
                .onClick(() => {
                    this.enabled_param = !this.enabled_param
                })
        }
        .width('100%')
        .height('100%')
        .alignItems(HorizontalAlign.Center)
        .backgroundColor(Color.Grey)
    }
}

3. 触摸测试控制

设置绑定Menu事件的组件的hitTestBehavior属性为HitTestMode.None,使其不响应触摸事件。

示例代码:

@Entry
@Component
struct menu {
    @State hitTestBehavior_param: HitTestMode = HitTestMode.Default
    @Builder
    MyMenu() {
        Menu()
    }
    build() {
        Column({ space: 30 }) {
            Blank()
                .height(100)
            Button('菜单')
                .bindMenu(this.MyMenu)
                .hitTestBehavior(this.hitTestBehavior_param)
            Button('HitTestMode = ' + this.hitTestBehavior_param)
                .onClick(() => {
                    if (this.hitTestBehavior_param == HitTestMode.Default) {
                        this.hitTestBehavior_param = HitTestMode.None
                    } else {
                        this.hitTestBehavior_param = HitTestMode.Default
                    }
                })
        }
        .width('100%')
        .height('100%')
        .alignItems(HorizontalAlign.Center)
        .backgroundColor(Color.Grey)
    }
}

通过以上方法,可以在Menu数据为空时实现不显示Menu的效果。

回到顶部