头图

前言

本文基于Api13

气泡提示,在很多场景下都会用到,比如常见的微信会话聊天中,长按某一条消息,就会弹出一个气泡提示,或者点击右上角的加号,也会弹出一个气泡选择,可以说应用十分广泛。

如下,长按某一条信息时:

image.png

点击右上角加号时:

image.png

以上的效果,在鸿蒙开发中,我们可以很快速的来实现,毕竟每一个组件都有一个通用的属性bindPopup,使用bindPopup可以很快速的实现一个气泡,想在哪个组件上进行弹出,就给哪个组件进行绑定。

简单案例如下:

@Entry
@Component
struct Index {
  @State isShowPopup: boolean = false

  build() {
    Column() {
      Button("点击")
        .onClick(() => {
          this.isShowPopup = !this.isShowPopup
        })
        .bindPopup(this.isShowPopup, {
          message: "我是一个简单的气泡",
          onStateChange: (e) => {
            this.isShowPopup = e.isVisible
          }
        })
    }
    .width("100%")
    .height("100%")
    .justifyContent(FlexAlign.Center)
  }
}

效果如下:

image.png

本文,我们就一起走进bindPopup的使用,同样在最后,我们也用自己的方式来实现一个自定义的Popup气泡提示。

一、bindPopup普通提示

最简单的就是一个普通的文本提示,也就是前言中的案例,直接设置一个message即可,通过第一个boolean类型参数可以控制气泡的显示和隐藏,除了这两个参数之外,它还有着很多的属性可供选择,我们挑几个比较常用的来简单概述一下。

箭头控制enableArrow

气泡默认是带有箭头的,如果你想隐藏箭头,可以通过属性enableArrow来控制,设置false即可。

 enableArrow: false, //隐藏箭头

我们看下设置后效果,可以看到箭头已经隐藏了。

image.png

圆角半径radius

默认的圆角半径为20vp,如果你想改变,可以通过radius属性来控制,比如设置圆角半径为0,代码如下:

radius:0,//圆角半径

效果如下:可以看到圆角半径已经为0了。

image.png

背景颜色popupColor

  /**
     * Set the background color of the popup.
     *
     * @type { ?(Color | string | Resource | number) }
     * @syscap SystemCapability.ArkUI.ArkUI.Full
     * @crossplatform
     * @atomicservice
     * @since 12
     */
    popupColor?: Color | string | Resource | number;

通过以上源码,我们可以看到,popupColor支持四种类型参数,Color 、string 、Resource和number。

我们直接选择其中一种类型传递即可。

 popupColor: Color.Pink,

如果大家仅仅设置这一个属性,会发现,背景颜色一闪而过,并没有显示出我们指定的颜色,这是因为模糊背景填充效果backgroundBlurStyle导致的,只需将backgroundBlurStyle设置为BlurStyle.NONE即可。

 backgroundBlurStyle: BlurStyle.NONE,

再次看下效果,就可以发现背景已经发生变化了。

image.png

遮罩颜色mask

默认遮罩是透明的,如果你想改变遮罩的颜色,可以使用mask来设置。

  /**
     * The mask to block gesture events of popup.
     * When mask is set false, gesture events are not blocked.
     * When mask is set true, gesture events are blocked and mask color is transparent.
     *
     * @type { ?(boolean | { color: ResourceColor }) }
     * @syscap SystemCapability.ArkUI.ArkUI.Full
     * @crossplatform
     * @atomicservice
     * @since 11
     */
    mask?: boolean | {
        color: ResourceColor;
    };

通过源码,我们可以看到,mask,不仅仅支持颜色,还支持一个boolean类型,其作用是如果设置为false,则不显示遮罩层;如果设置为true,则显示透明色遮罩层。

我们直接使用颜色即可,比如我想设置遮罩颜色为80%透明色,代码如下:

mask:{color:"#80000000"}

效果如下:

image.png

设置间距targetSpace

如果你需要修改气泡弹窗与目标组件之间的间距,可以使用targetSpace属性来修改,参数类型是Length,比如,我修改与目标组件间距为20。

targetSpace:20

效果如下,可以看到,与默认相比,明显间距变大了。

image.png

显示位置placement

通过属性placement,我们可以设置气泡弹窗的显示位置,默认位置是底部显示,也就是Placement.Bottom,可供选择的值如下:

名称说明
Left气泡提示位于组件左侧,与组件左侧中心对齐。
Right气泡提示位于组件右侧,与组件右侧中心对齐。
Top气泡提示位于组件上侧,与组件上侧中心对齐。
Bottom气泡提示位于组件下侧,与组件下侧中心对齐。
TopLeft气泡提示位于组件上侧,从API Version 9开始,与组件左侧边缘对齐。
TopRight气泡提示位于组件上侧,从API Version 9开始,与组件右侧边缘对齐。
BottomLeft气泡提示位于组件下侧,从API Version 9开始,与组件左侧边缘对齐。
BottomRight气泡提示位于组件下侧,从API Version 9开始,与组件右侧边缘对齐。
LeftTop9+气泡提示位于组件左侧,与组件上侧边缘对齐。
LeftBottom9+气泡提示位于组件左侧,与组件下侧边缘对齐。
RightTop9+气泡提示位于组件右侧,与组件上侧边缘对齐。
RightBottom9+气泡提示位于组件右侧,与组件下侧边缘对齐。

比如,我要设置显示在上边,就可以如下设置:

placement:Placement.Top

效果如下:

image.png

除了以上常见的属性之外,还有很多可供选择的属性,比如箭头的位置,偏移量,获取焦点,宽度以及气泡状态监听等等,这里就不赘述了,了解的可以去官网查看即可。

有的友友可能就发问了,我的气泡提示也不是简单的文字提示啊,而是和微信一样的复杂视图,如何实现呢,这个实现起来也是非常的简单,通过builder属性。

二、bindPopup自定义组件

bindPopup中除了简单的文字提示之外,也给我们提供一个可以传递自定义组件的属性,那就是builder,通过builder,我们就可以自己绘制视图,实现多样的布局效果。

简单案例:

@Entry
@Component
struct Index {
  @State isShowPopup: boolean = false

  @Builder
  popupBuilder() {
    Column() {
      ForEach([1, 2, 3, 4, 5], (item: number) => {
        Row() {
          Image($r("app.media.app_icon"))
            .width(20)
            .height(20)
          Text("条目" + item)
            .textAlign(TextAlign.Center)
            .margin({ left: 5 })
        }.width(100)
        .height(40)
        .justifyContent(FlexAlign.Center)
        .border({ width: { bottom: 1 }, color: "#e8e8e8" })
      })
    }
  }

  build() {
    Column() {
      Button("点击")
        .onClick(() => {
          this.isShowPopup = !this.isShowPopup
        })
        .bindPopup(this.isShowPopup, {
          builder: this.popupBuilder,
          radius: 5,
          onStateChange: (e) => {
            this.isShowPopup = e.isVisible
          }
        })
    }
    .width("100%")
    .height("100%")
    .justifyContent(FlexAlign.Center)
  }
}

效果如下:

image.png

以上的两种方式,基本上可以满足我们绝大多数的气泡需求,但是有的友友又说了,实现一个气泡还得要绑定,有点麻烦啊,有没有一种方式,我想怎么弹就怎么弹,不用通过绑定的形式实现呢,哎,这个是有的,那就是通过openCustomDialog来实现。

三、dialog库实现

通过openCustomDialog,我们可以自绘制任意的组件弹窗,以dialog的形式来实现popup气泡提示,唯独需要确定的是显示组件的坐标位置,这个我们放到下篇文章概述,本篇我们只简单了解一下具体的使用方式。

两种依赖方式,选择其一即可。

方式一:在Terminal窗口中,执行如下命令安装三方包,DevEco Studio会自动在工程的oh-package.json5中自动添加三方包依赖。

建议:在使用的模块路径下进行执行命令。

ohpm install @abner/dialog

方式二:在工程的oh-package.json5中设置三方包依赖,配置示例如下,目前最新版本是1.2.0。

"dependencies": { "@abner/dialog": "^1.2.0"}

简单使用

import { showPopupWindow, PopupDirection } from "@abner/dialog"

@Builder
function popupBuilder() {
  Column() {
    ForEach([1, 2, 3, 4, 5], (item: number) => {
      Row() {
        Image($r("app.media.app_icon"))
          .width(20)
          .height(20)
        Text("条目" + item)
          .textAlign(TextAlign.Center)
          .margin({ left: 5 })
          .fontColor(Color.White)
      }.width(100)
      .height(40)
      .justifyContent(FlexAlign.Center)
      .border({ width: { bottom: 1 }, color: "#e8e8e8" })
    })
  }.backgroundColor(Color.Black)
  .margin({ top: 10 })
}

@Entry
@Component
struct Index {
  build() {
    Column() {
      Button("点击")
        .id("popupBottom")
        .onClick(() => {
          showPopupWindow({
            id: "popupBottom",
            view: wrapBuilder(popupBuilder),
            direction: PopupDirection.BOTTOM,
          })
        })
    }
    .width("100%")
    .height("100%")
    .justifyContent(FlexAlign.Center)
  }
}

效果展示

image.png

支持很多方向,比如左上右下,左上右下,左下右上,通过direction控制即可。

弹出上

showPopupWindow({
            id: "popupTop",
            view: wrapBuilder(BuilderWindowView)
          })

弹出下

showPopupWindow({
  id: "popupBottom",
  view: wrapBuilder(BuilderWindowView),
  direction: PopupDirection.BOTTOM
})

携带参数

let params = new WindowParams()
          params.title = "我是携带的参数"
          showPopupWindow({
            id: "popupParams",
            params: params,
            viewParams: wrapBuilder(BuilderWindowParams),
            direction: PopupDirection.BOTTOM
          })

更新数据

let params = new WindowParams()
    params.title = "嘿嘿,我更新了"
    updatePopupData(params)

任意位置

showPopupWindow({
  view: wrapBuilder(BuilderWindowView),
  x: 60,
  y: 300
})

相关总结

原生的bindPopup属性,不仅仅支持单一的文字提示,也支持自定义组件的形式,已经可以满足正常的需求开发,能用原生的就用原生,之所以dialog库中增加了一个popup气泡弹窗,是因为当时封装的时候,原生还不支持自定义组件形式,如今已经支持了,大家可以放心的使用原生即可。

当然,如果你不想实现绑定的形式,想自由的弹出,那么可以使用dialog库中提供的,一个id便可以定位到需要弹出的组件上,使用起来也是非常的简单。

文章标签:HarmonyOSNext/ArkUI


程序员一鸣
19 声望1 粉丝