Bootstrap

鸿蒙开发之下拉菜单Menu

鸿蒙定义了很好的下拉组件,对比原生iOS或android需要自定义来说确实简单太多了,而且原生相对自定义来说要稳定太多了。

上图来自官网案例。

一、API使用

Menu作为容器组件,内部使用MenuItem作为每一条的选项。其中,通过MenuItem控制具体的选项信息。

MenuItem可以传递参数

startIcon?: ResourceStr; //起始位置的图标

content?: ResourceStr; //内容,左侧标题

endIcon?: ResourceStr; //末尾位置的图标

labelInfo?: ResourceStr; //末尾的内容(浅灰色)

builder?: CustomBuilder; //自定义的组件,可以用作子选项
Menu() { 
    MenuItem({
        content: 'item2',
        labelInfo:'value2',
        builder: xxx,
        startIcon: $rawfile('111.png'),
        endIcon: $r('app.media.icon')
      })
}

二、子选项

通过MenuItem的builder参数,绑定一个子选项

  @Builder subMenu() {
    MenuItem({content:'item1',labelInfo:'value1'})
    MenuItem({content:'item1',labelInfo:'value1'})
  }


@Builder myMenu() {
    Menu() {
      MenuItem({content:'item1',labelInfo:'value1'})
      MenuItem({
        content: 'item2',
        builder: this.subMenu.bind(this),
        startIcon: $rawfile('111.png'),
        endIcon: $r('app.media.icon')
      })
    }
  }

三、菜单组

Menu内部可以放MenuItemGroup,对菜单进行分组

@State menuSelected: boolean = true
@Builder myMenu() {
    Menu() {
   
      MenuItemGroup({ header: '菜单组' }) {
        MenuItem({ content: "选项一" })
            //选中状态图标显示
          .selectIcon(true)
            //切换是否选中
          .selected(this.menuSelected)
            //切换选中回调
          .onChange((selected) => {
            console.info("menuItem select" + selected);
            this.menuSelected = selected
          })
        MenuItem({
          startIcon: $r("app.media.app_icon"),
          content: "选项二",
          endIcon: $r("app.media.icon"),
        })
      }
    }
  }

四、完整代码

@Entry
@Component
struct OfficialMenuPage {
  @State menuSelected: boolean = true

  @Builder subMenu() {
    MenuItem({content:'item1',labelInfo:'value1'})
    MenuItem({content:'item1',labelInfo:'value1'})
  }

  @Builder myMenu() {
    Menu() {
      MenuItem({content:'item1',labelInfo:'value1'})
      MenuItem({
        content: 'item2',
        builder: this.subMenu.bind(this),
        startIcon: $rawfile('111.png'),
        endIcon: $r('app.media.icon')
      })

      MenuItemGroup({ header: '菜单组' }) {
        MenuItem({ content: "选项一" })
          .selectIcon(true)
          .selected(this.menuSelected)
          .onChange((selected) => {
            console.info("menuItem select" + selected);
            this.menuSelected = selected
          })
        MenuItem({
          startIcon: $r("app.media.app_icon"),
          content: "选项二",
          endIcon: $r("app.media.icon"),
          builder: this.subMenu.bind(this)
        })
      }

      MenuItem({
        startIcon: $r('app.media.app_icon'),
        content: "选项三",
        endIcon: $r("app.media.app_icon")
      })
    }
  }

  build() {
    Row() {
      Column() {
        Text('点击展示')
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
          .bindMenu(this.myMenu)
      }
      .width('100%')
    }
    .height('100%')
  }
}

五、问题

Menu组件的builder属性本来是可以用来做子选项的,但是在模拟器和预览中不能展示。一开始以为是代码问题,后来用官方代码也一样不能展示,也算是不支持模拟器和预览了。

;