Skip to content

公共提示类属性

ArkUI 开发框架提供了全局方法 bindMenubindPopup ,方便开发者合理利用弹窗选项给用户友好交互操作的体验,本节笔者介绍一下它们的简单使用

bindMenu

bindMenu 表示给当前组件绑定一个菜单项,用户点击组件后弹出菜单, bindMenu 定义如下:

bash

declare class CommonMethod<T> {
  bindMenu(content: { value: string; action: () => void }[] | CustomBuilder): T;
}

content 参数支持单项文本和自定义两种方式,这两种实现分别如下:

单项文本实现

content 类型为 { value: string; action: () => void } 时, value 表示要显示的菜单文本, action 表示点击该文本的事件回调,简单样例如下所示:

bash

import promptAction from '@ohos.promptAction';
@Entry @Component struct Index {
  build() {
    Column({space: 10}) {
      Button("bindMenu")
        .width(120)
        .height(50)
        .onClick(() => {
          promptAction.showToast({message: "bindMenu",duration:3000,bottom:100})
        })
        .bindMenu([
          {
            value: "菜单1",
            action: () => {
              promptAction.showToast({message: "菜单1",duration:3000,bottom:100})
            }
          },
          {
            value: "菜单2",
            action: () => {
              promptAction.showToast({message: "菜单2",duration:3000,bottom:100})
            }
          },
          {
            value: "菜单3",
            action: () => {
              promptAction.showToast({message: "菜单3",duration:3000,bottom:100})
            }
          }
        ])
    }
    .padding(10)
    .size({ width: "100%", height: '100%' })
  }
}

图片

从运行结果看,使用单项文本实现一个菜单,文字太小并且样式和布局均无法修改,这种方式 UI 局限性太大,为了满足多样式场景需求,ArkUI 开发框架提供了 CustomBuilder 方式允许开发者自定义 UI 描述。

CustomBuilder 方式实现

CustomBuildercommon.d.ts 文件中定义,源码定义如下:

bash

declare type CustomBuilder = (() => any) | void;

CustomBuilder 即可代表一个空类型也可以表示一个返回任意类型的函数,自定义 UI 描述使用 @Builder 装饰器装饰一个方法,该方法功能和语法规范和 build 函数相同,返回一个 UI 布局,格式如下所示:

bash

@Builder function
function_name() { // @Builder修复一个方法
  // UI布局
  Column() {
  }
}

用户自定义 UI 实现,就是使用 @Builder 修饰一个方法,该方法返回一个 UI 布局即可,简单样例如下所示

bash
import promptAction from '@ohos.promptAction';

@Entry
@Component
struct Index {
  build() {
    Column({ space: 10 }) {
      Button("bindMenu")
        .width(120)
        .height(50)
        .onClick(() => {
          promptAction.showToast({ message: "bindMenu", duration: 3000, bottom: 100 })
        })
        .bindMenu(
          MenuList()
        )
    }
    .padding(10)
    .size({ width: "100%", height: '100%' })
  }
}

@Extend(Text)
function TextStyle() {
  .fontSize(24)
  .fontColor(Color.Red)
}

@Builder
function MenuList() {
  Column({ space: 20 }) {
    Row() {
      Text("张三").TextStyle()
    }.onClick(() => {
      promptAction.showToast({ message: "张三", duration: 3000, bottom: 100 });
    })

    Row() {
      Image($r("app.media.app_icon")).width(24).height(24)
      Text("游客头像").TextStyle().onClick(() => {
        promptAction.showToast({ message: "游客头像", duration: 3000, bottom: 100 });
      })
    }

    Row() {
      Image($r("app.media.app_icon")).width(24).height(24)
      Text("管理员头像").TextStyle().onClick(() => {
        promptAction.showToast({ message: "管理员头像", duration: 3000, bottom: 100 });
      })
    }
  }
}

图片

由样例可知, Button 同时设置了 onClickbindMenu 方法, onClick 方法不起作用,对于这种场景,可以使用 bindContextMenu 方法代替。

bindContextMenu

这样就不会触发点击事件

该方法只有在长按或者右键点击组件是才会触发显示菜单项,这样就完美解决了和点击事件冲突的问题。 bindContextMenu 定义如下:

bash

declare class CommonMethod<T> {
  bindContextMenu(content: CustomBuilder, responseType: ResponseType): T;
}
  • content:参数只支持使用 CustomBuilder 自定义 UI 一种方式,

  • responseType:触发弹窗的响应类型, ResponseType 定义了一下两种类型:

LongPress: 通过长按触发菜单弹出。

RightClick:通过鼠标右键触发菜单弹出。

样例长按

bash

import promptAction from '@ohos.promptAction';

@Entry
@Component
struct Index {
  build() {
    Column({ space: 10 }) {
      Button("bindMenu")
        .width(120)
        .height(50)
        .onClick(() => {
          promptAction.showToast({ message: "bindMenu", duration: 3000, bottom: 100 })
        })
        .bindContextMenu(
          MenuList(),
          ResponseType.LongPress
        )
    }
    .padding(10)
    .size({ width: "100%", height: '100%' })
  }
}

@Extend(Text)
function TextStyle() {
  .fontSize(24)
  .fontColor(Color.Red)
}

@Builder
function MenuList() {
  Column({ space: 20 }) {
    Row() {
      Text("张三").TextStyle()
    }.onClick(() => {
      promptAction.showToast({ message: "张三", duration: 3000, bottom: 100 });
    })

    Row() {
      Image($r("app.media.app_icon")).width(24).height(24)
      Text("游客头像").TextStyle().onClick(() => {
        promptAction.showToast({ message: "游客头像", duration: 3000, bottom: 100 });
      })
    }

    Row() {
      Image($r("app.media.app_icon")).width(24).height(24)
      Text("管理员头像").TextStyle().onClick(() => {
        promptAction.showToast({ message: "管理员头像", duration: 3000, bottom: 100 });
      })
    }
  }
}

图片

bindPopup

bindPopupbindMenu 功能类似,从用户角度讲都是弹出一个可选项提示框, bindPopup 定义如下:

bash

declare class CommonMethod<T> {
  bindPopup(show: boolean, popup: PopupOptions | CustomPopupOptions): T;
}
  • show:创建 Popup 弹窗时是否默认显示,默认值为 false

  • popupPopup 的显示配置,参数支持 PopupOptionsCustomPopupOptions 两种类型,他们分别如下所示:

PopupOptions 配置如下:

bash

declare interface PopupOptions {
  message: string;                                         // 显示的信息提示
  placementOnTop?: boolean;                                // 是否显示在组件上方,默认值为 false
  primaryButton?: {                                        // 第一个按钮的配置
    value: string;                                         // 按钮的文字
    action: () => void;                                    // 按钮的点击回调
  };
  secondaryButton?: {                                      // 第二个按钮的配置
    value: string;                                         // 按钮的文字
    action: () => void;                                    // 按钮的事件回调
  };
  onStateChange?: (event: { isVisible: boolean }) => void; // Popup可见性变化的回调
}
  • message: Popup 显示的提示文字。

  • placementOnTop: Popup 是否显示在组件上方。

  • primaryButton: Popup 显示按钮配置。

  • secondaryButton: Popup 显示按钮配置。

  • onStateChange: Popup 可见性变化的回调。

简单示例:

bash

import promptAction from '@ohos.promptAction';

@Entry
@Component
struct Index {
  @State showPopup:boolean = false;
  build() {
    Column({ space: 10 }) {

      Button("bindPopup")
        .width(120)
        .height(50)
        .bindPopup(this.showPopup, {
          message: "bindPopup测试",
          placementOnTop: true,
          onStateChange: ((state) => {
            promptAction.showToast({message: "isVisible: " + state.isVisible})
          }),
          primaryButton: {
            value: "测试1",
            action: () => {
              promptAction.showToast({message: "测试1"})
              this.showPopup = !this.showPopup;
            }
          },
          secondaryButton: {
            value: "测试2",
            action: () => {
              promptAction.showToast({message: "测试2"})
              this.showPopup = !this.showPopup;
            }
          }
        })
        .onClick(() => {
          this.showPopup = !this.showPopup;
        })
    }
    .padding(10)
    .size({ width: "100%", height: '100%' })
  }
}

图片

CustomPopupOptions 配置如下:

bash

declare interface CustomPopupOptions {
  builder: CustomBuilder;
  placement?: Placement;
  maskColor?: Color | string | Resource | number;
  popupColor?: Color | string | Resource | number;
  enableArrow?: boolean;
  autoCancel?: boolean;
  onStateChange?: (event: { isVisible: boolean }) => void;
}
  • builder:自定义 Popup 。

  • placement: Popup 的相对位置。

  • maskColor: Popup 蒙层颜色。

  • popupColor: Popup 背景颜色。

  • enableArrow: Popup 是否显示箭头。

  • autoCancel: Popup 是否自动隐藏。

  • onStateChange: Popup 可见性变化的回调。

简单样例如下所示:

bash

import promptAction from '@ohos.promptAction';

@Entry
@Component
struct Index {
  @State showPopup:boolean = false;
  build() {
    Column({ space: 10 }) {

      Button("bindPopup")
        .width(120)
        .height(50)
        .bindPopup(this.showPopup, {
          builder:MenuList(), // 自定义UI
          placement:Placement.Bottom, // 按钮下方显示
          maskColor:"black", // 蒙层颜色
          popupColor:"green", // 背景色
          enableArrow:true, // 是否显示箭头
          autoCancel:false, // 设置自动隐藏
          onStateChange: ((state) => {
            promptAction.showToast({message: "isVisible: " + state.isVisible})
          })
        })
        .onClick(() => {
          this.showPopup = !this.showPopup;
        })

    }
    .padding(10)
    .size({ width: "100%", height: '100%' })
  }
}

@Extend(Text)
function TextStyle() {
  .fontSize(24)
  .fontColor(Color.Red)
}

@Builder
function MenuList() {
  Column({ space: 20 }) {
    Row() {
      Text("张三").TextStyle()
    }.onClick(() => {
      this.showPopup = !this.showPopup;
      promptAction.showToast({ message: "张三", duration: 3000, bottom: 100 });
    })

    Row() {
      Image($r("app.media.app_icon")).width(24).height(24)
      Text("游客头像").TextStyle().onClick(() => {
        this.showPopup = !this.showPopup;
        promptAction.showToast({ message: "游客头像", duration: 3000, bottom: 100 });
      })
    }

    Row() {
      Image($r("app.media.app_icon")).width(24).height(24)
      Text("管理员头像").TextStyle().onClick(() => {
        this.showPopup = !this.showPopup;
        promptAction.showToast({ message: "管理员头像", duration: 3000, bottom: 100 });
      })
    }
  }
}

图像