气泡提示(Popup)与菜单(Menu)

发布于:2025-08-29 ⋅ 阅读:(15) ⋅ 点赞:(0)

1.气泡提示(Popup)

Popup属性可绑定在组件上显示气泡弹窗提示,设置弹窗内容、交互逻辑和显示状态。
在这里插入图片描述
气泡分为两种类型:一种是系统提供的气泡PopupOptions,一种是自定义的气泡CustomPopupOptions。
● 其中PopupOptions为系统提供的气泡,通过配置primaryButton、secondaryButton来设置带按钮的气泡。
● CustomPopupOptions通过配置builder参数来设置自定义的气泡。

1.1 文本提示气泡

文本提示气泡常用于只展示带有文本的信息提示,不带有任何交互的场景。
在这里插入图片描述

@Entry
@Component
struct PopupExample {
  @State handlePopup: boolean = false

  build() {
    Column() {
      Button('显示气泡')
        .bindPopup(this.handlePopup, {
          message: '这是气泡的内容',
          onStateChange: (e) => {				//气泡发生改变时调用
            if (!e.isVisible) {
              this.handlePopup = false
            }
          }
        })
        .onClick(() => {
          this.handlePopup = !this.handlePopup
        })
    }.width('100%').padding({ top: 5 })
  }
}

1.2 带按钮的气泡

通过primaryButton、secondaryButton属性为气泡最多设置两个Button按钮,通过此按钮进行简单的交互,开发者可以通过配置action参数来设置想要触发的操作。
在这里插入图片描述

@Entry
@Component
struct PopupExample22 {
  @State handlePopup: boolean = false

  build() {
    Column() {
      Button('PopupOptions').margin({ top: 200 })
        .onClick(() => {
          this.handlePopup = !this.handlePopup
        })
        .bindPopup(this.handlePopup, {
          message: 'This is a popup with PopupOptions',
          primaryButton: {
            value: 'Confirm',
            action: () => {
              this.handlePopup = !this.handlePopup
              console.info('confirm Button click')
            }
          },
          secondaryButton: {
            value: 'Cancel',
            action: () => {
              this.handlePopup = !this.handlePopup
            }
          },
          onStateChange: (e) => {
            if (!e.isVisible) {
              this.handlePopup = false
            }
          }
        })
    }.width('100%').padding({ top: 5 })
  }
}

1.3 自定义气泡

手机上点击应用图标时会弹出一个气泡,可以进行分享、卸载等操作。我们现在也可以做一个类似的效果出来,长按图片弹出气泡。如下图所示
在这里插入图片描述

  1. 在Index中用@Builder构建气泡的内容。
@Entry
@Component
struct Index{
  //1.自定义气泡内容
  @Builder
  InfoPopup() {
    Column({ space: 10 }) {
      Row({ space: 20 }) {
        SymbolGlyph($r('sys.symbol.info_circle')).fontWeight(FontWeight.Medium)
        Text('应用信息').fontSize(12).fontWeight(FontWeight.Normal)
      }

      Row({ space: 20 }) {
        SymbolGlyph($r('sys.symbol.share')).fontWeight(FontWeight.Medium)
        Text('分享').fontSize(12).fontWeight(FontWeight.Normal)
      }

      Row({ space: 20 }) {
        SymbolGlyph($r('sys.symbol.trash')).fontWeight(FontWeight.Medium)
        Text('卸载').fontSize(12).fontWeight(FontWeight.Normal)
      }
    }
    .width(150)
      .height(100)
      .padding(5)
      .alignItems(HorizontalAlign.Start)
      .padding({ left: 10, top: 20 })
  }

  //2.构建页面的函数
  build(){
    ...
  }
}
  1. 在Index的build函数中,使用Image放置一张图片,长按图片弹出自定义气泡。
@Entry
@Component
struct Index{
  //1.自定义气泡内容
  ...

  //2.构建页面的函数
  handlePopup: boolean =false
  build(){
     Column() {
      Image($r('app.media.huawei_watch'))
        .width(100)
        .width(100)
        .margin({ top: 200 })
        .draggable(false)	//Image是默认是可拖拽控件,与长按手势有冲突,所以必须禁止拖拽。
        .gesture(LongPressGesture({duration: 500 })	//添加长按手势
          .onAction((event: GestureEvent) => {
            this.handlePopup = !this.handlePopup
          }))
        .bindPopup(this.handlePopup, {		//给图片绑定气泡
          builder: this.InfoPopup(),
          onStateChange: (e) => {
            if (!e.isVisible) {
              this.handlePopup = false
            }
          }
        })
    }.width('100%').padding({ top: 5 })
  }
}

手势是一个通用事件,任何组件都可以绑定手势事件
● 通过.gesture(手势类型)给组件绑定手势识别
● LongPressGesture 用于触发长按手势事件,触发长按手势的最少手指数为1,最短长按时间为500毫秒。

Button('长按')
  .gesture(
    LongPressGesture({
      fingers:1,  //长按最少得手指个数
      repeat: true, //是否重复触发手势回调,默认为false
      duration: 1000, //长按触发时间,1000毫秒
    })
    .onAction((event:GestureEvent)=>{
      //长按完成触发
        console.log('长按触发')
    })
    .onActionEnd((event:GestureEvent)=>{
      //长按完成,手指抬起后触发回调。
        console.log('长按释放')
    })
  ) 

2.菜单(Menu)

Menu是菜单接口,一般用于鼠标右键弹窗、点击弹窗等。

2.1 默认菜单

如果下图所示,点击按钮时就可以弹出一个菜单,有3个菜单项,每一个菜单项用MenuElement表示。
在这里插入图片描述
代码如下,给按钮绑定菜单,调用bindMenu(content: Array)属性。

Entry
@Component
struct Index {
  build() {
    Column() {
      Button('click for Menu')
        .bindMenu([
          //第一个菜单项
          {
            value: 'Menu1',
            action: () => {
              console.warn('handle Menu1 select')
            }
          },
          //第二个菜单项
          {
            value: 'Menu2',
            action: () => {
              console.warn('handle Menu1 select')
            }
          },
          //第三个菜单项
          {
            value: 'Menu3',
            action: () => {
              console.warn('handle Menu1 select')
            }
          }
        ])
    }.width('100%').padding({ top: 5 })
  }
}

2.2 自定义菜单

当默认样式不满足开发需求时,可使用@Builder自定义菜单内容。通过bindMenu接口进行菜单的自定义。
如:我们想要实现下面的菜单样式,而且二级菜单,此时就只能用自定义菜单了。

在这里插入图片描述
● 菜单是一个容器,整个菜单用Enum表示
● 每一个菜单项用EnumItem表示,每一个菜单项由三个部分组成(图片,文字,图片)
● 可以把多个菜单项归为一组,用MenuItemGrop(‘分组标题’)
根据上面分析把菜单内容构建出来,使用@Builder装饰。

@Entry
@Component
struct Index {
  //1.一级菜单
  @Builder
  MyMenu() {
    Menu() {
      MenuItem({ startIcon: $r('app.media.startIcon'), content: '菜单选项1' })
      MenuItem({ startIcon: $r('app.media.startIcon'), content: '菜单选项2' }).enabled(false)
      MenuItem({
        startIcon: $r('sys.media.ohos_ic_public_share'),
        content: '菜单选项3',
        endIcon: $r('sys.media.ohos_ic_public_arrow_right'),
        builder: this.SubMenu()
      })
      MenuItemGroup({ header: '小标题' }) {
        MenuItem({ startIcon: $r('sys.symbol.list_checkmask'), content: '菜单选项4' })
          .selectIcon(true)//显示选中图标,在选项前打一个✅
          .selected(true)//是否选中
          .onChange((selected) => {
            console.info("menuItem select:" + selected) //选中
          })
        MenuItem({
          startIcon: $r('sys.media.ohos_ic_public_text'),
          content: '菜单选项5',
          endIcon: $r('sys.media.ohos_ic_public_arrow_right')
        })
      }

      MenuItem({
        startIcon: $r('sys.media.ohos_ic_public_voice_off'),
        content: '菜单选项6',
        endIcon: $r('sys.media.ohos_ic_public_arrow_right')
      })
    }.width(200)
  }

  //2.二级菜单
  @Builder
  SubMenu() {
    Menu() {
      MenuItem({ content: "复制", labelInfo: "Ctrl+C" })
      MenuItem({ content: "粘贴", labelInfo: "Ctrl+V" })
    }
  }

  //3.将一级菜单绑定到按钮上
  build() {
    Column() {
      Button('菜单').bindMenu(this.MyMenu())
    }.width('100%').alignItems(HorizontalAlign.Center).margin({ top: 20 })
  }
}

网站公告

今日签到

点亮在社区的每一天
去签到