鸿蒙对话框封装

499 阅读2分钟

鸿蒙对话框封装

前言

鸿蒙也搞了几个月了,感觉自己还是个菜鸡,而且这破环境下,适配新的鸿蒙系统,又不给时间学习,又不给足够的工时,心态有点绷不住。

这篇文章也是个简单的功能,就是封装了一个简单的对话框组件,踩了些坑,记录下。

鸿蒙对话框

在封装对话框前,这里先了解下鸿蒙的对话框如何使用,可以先看官方的参考文档:

自定义弹窗 CustomDialog

其实就是用CustomDialog注解的一个组件,比如像下面这样:

@CustomDialog
struct CustomDialogExample {
  controller: CustomDialogController = new CustomDialogController({
    builder: CustomDialogExample({}),
  })

  build() {
    Column() {
      Text('我是内容')
        .fontSize(20)
        .margin({ top: 10, bottom: 10 })
    }
  }
}

简单对话框封装

这里简单写一个带确认和取消的对话框,并能够修改里面内容,获取回调:

/**
 * 中间提示的弹框
 */
@CustomDialog
export struct CenterTipPop {
  @State param: ControlParam = new ControlParam();
  controller: CustomDialogController;
  onCancel?: () => void;

  @Styles
  itemPressedStyle() {
    .backgroundColor('#804b8cf1')
  }

  @Styles
  itemNormalStyle() {
    .backgroundColor('#4B8CF1')
  }

  build() {
    Column({ space: 0 }) {
      Text(this.param.title)
        .fontColor(Color.Black)
        .fontSize(16)
        .maxLines(1)
        .height(50)

      Text(this.param.content)
        .height(100)
        .fontColor(Color.Black)
        .fontSize(14)
        .backgroundColor(Color.Transparent)
        .textAlign(TextAlign.Center)

      Row() {
        if (!this.param.hideLeftBtn) {
          Text(this.param.cancelText)
            .width('50%')
            .height(50)
            .fontColor(Color.Black)
            .fontSize(16)
            .margin({ top: 15 })
            .backgroundColor(Color.White)
            .textAlign(TextAlign.Center)
            .stateStyles({
              pressed: this.itemPressedStyle
            })
            .onClick(() => {
              if (this.controller) {
                this.controller.close();
              }
              this.param.onCancel();
            })
            .borderRadius({
              bottomLeft: 15,
            })
        }

        Text(this.param.confirmText)
          .width(this.param.hideLeftBtn ? "100%" : '50%')
          .height(50)
          .fontColor(Color.White)
          .fontSize(16)
          .margin({ top: 15 })
          .backgroundColor("#4B8CF1")
          .textAlign(TextAlign.Center)
          .stateStyles({
            normal: this.itemNormalStyle,
            pressed: this.itemPressedStyle
          })
          .onClick(() => {
            if (this.controller) {
              this.controller.close();
            }
            this.param.onConfirm();
          })
          .borderRadius({
            bottomLeft: this.param.hideLeftBtn ? 15 : 0,
            bottomRight: 15
          })
      }
      .width('100%')

    }
    .alignItems(HorizontalAlign.Center)
    .width('80%')
    .backgroundColor('#f8f8f8')
    .borderRadius({
      topLeft: 15,
      topRight: 15,
      bottomLeft: 15,
      bottomRight: 15
    })
  }
}

我这里用了一个对象来保存参数和回调方法:

export class ControlParam {
  title: string = "";
  content: string = "";
  cancelText: string = "";
  confirmText: string = "";
  hideLeftBtn: boolean = false;
  onCancel: () => void = () => {};
  onConfirm: () => void = () => {};
}

这里能避过一些坑,比如鸿蒙中,父view的state变量传给子view的prop属性,父view的state变量发生变化,子view的内容也会更新。 但是,如果我们传入的是父view某个state变量的属性,那么这样的动态更新就失效了。

这时候对象的作用就体现出来了,我们直接给子view传入一个state的对象属性,在外部,我们随便修改对象属性,在子view中都会自动更新。

对话框的使用

对话框的使用这里也有大坑,首先这个CustomDialogController的创建一定要在struct里面创建:

    // 从其他任意地方来的对象
    this.textParam = ...;
    
    // 持有这个CustomDialogController
    this.textDialogController = new CustomDialogController({
      builder: CenterTipPop(
        {
          param: this.textParam,
          controller: this.textDialogController
        }),
      cancel: () => {},
      autoCancel: true,
      alignment: DialogAlignment.Center,
      customStyle: true
    });

拿到参数对象和CustomDialogController后,我们就能在想要修改对话框效果和显示了:

this.textParam.title = "温馨提示";
this.textParam.content = message;
this.textParam.cancelText = cancelBtnText;
this.textParam.confirmText = confirmBtnText;
this.textParam.hideLeftBtn = false;
this.textParam.onCancel = () => {
  resolve("cancel")
};
this.textParam.onConfirm = () => {
  resolve("confirm")
};

this.textDialogController.open();

只要页面不销毁,我们持有这个CustomDialogController就能随意弹对话窗了,效果图如下:

8ce6364b410a903b0edd80fe3b8f5fd.jpg

小结

简单封装了一个鸿蒙对话框,讲了讲如何创建一个自定义对话框,如何在想要使用的地方更新其中内容、显示、关闭。