鸿蒙 自定义弹窗对CustomDialogController二次封装

前言:

鸿蒙官方提供了自定义customdialog,调用代码很臃肿,必须在当前页面创建customDialogController,否则无法正常弹窗dialog

解决方案:目前就定义了两种类型的dialog

具体代码如下:

1. 用于代理dialog的打开和关闭

export interface MyCustomDialogController {
  open: () => void
  close: () => void
}

2. 作为全局弹窗组件封装 内容完全由外部dialogContent定义

@CustomDialog
export default struct MyCustomDialog {
  controller: CustomDialogController
  @BuilderParam dialogContent: () => void

  build() {
    this.dialogContent()
  }
}

3.1. 具体实现,这里是ConfirmPop(对话框弹窗)

import MyCustomDialog from './core/MyCustomDialog';
import { MyCustomDialogController } from './core/MyCustomDialogController';
/**
 * @author: hwk
 * @description: 确认取消对话框弹窗
 * @date: 2024/3/7 10:33
 */
@Component
export default struct ConfirmPop {
  controller: MyCustomDialogController = null;
  alignment: DialogAlignment = DialogAlignment.Center; //弹窗位置
  offsetX: number = 0; //上下 偏移量 负数则往上
  offsetY: number = 0; //上下 偏移量 负数则往上
  autoCancel: boolean = false; //点击遮罩层是否关闭弹窗
  //api9不支持 maskColor: ResourceColor = "rgba(0,0,0,0.1)";
  customStyle: true;
  title: Resource;
  content: Resource;
  leftText: Resource = $r('app.string.quxiao');
  rightText: Resource = $r('app.string.queding');
  isHideRight: boolean = false; //是否隐藏右边按钮
  leftClick: () => void
  rightClick: () => void

  //下面两个是私有的
  @State leftDown: boolean = false; //左边按钮是否按下
  @State rightDown: boolean = false; //右边按钮是否按下


  build() {
  }

  @Builder buildContent() {
    Column() {
      Text(this.title)
        .fontSize(15)
        .fontColor($r('app.color.black3'))
        .maxLines(1)
        .textOverflow({ overflow: TextOverflow.Ellipsis })
      Text(this.content)
        .fontSize(13)
        .fontColor($r('app.color.black6'))
        .maxLines(3)
        .textOverflow({ overflow: TextOverflow.Ellipsis })
        .margin({ top: 13, bottom: 30 })
      Row() {
        Text(this.leftText)
          .height('100%')
          .width(86)
          .textAlign(TextAlign.Center)
          .fontSize(13)
          .backgroundColor(this.leftDown ? $r('app.color.theme') : $r('app.color.white'))
          .fontColor(this.leftDown ? $r('app.color.white') : $r('app.color.theme'))
          .border({ width: 1, color: $r('app.color.theme'), radius: 5, style: BorderStyle.Solid })
          .onTouch((event: TouchEvent) => {
            this.leftDown = (event.type != TouchType.Up);
          })
          .onClick(() => {
            this.controller.close()
            if (this.leftClick)
              this.leftClick()
          })

        Blank()
          .visibility(this.isHideRight ? Visibility.None : Visibility.Visible)
          .width(20)
          .height('100%')

        Text(this.rightText)
          .visibility(this.isHideRight ? Visibility.None : Visibility.Visible)
          .height('100%')
          .width(86)
          .textAlign(TextAlign.Center)
          .fontSize(13)
          .backgroundColor(this.rightDown ? $r('app.color.theme') : $r('app.color.white'))
          .fontColor(this.rightDown ? $r('app.color.white') : $r('app.color.theme'))
          .border({ width: 1, color: $r('app.color.theme'), radius: 5, style: BorderStyle.Solid })
          .onTouch((event: TouchEvent) => {
            this.rightDown = (event.type != TouchType.Up);
          })
          .onClick(() => {
            this.controller.close()
            if (this.rightClick)
              this.rightClick()
          })
      }
      .width('100%')
      .height(34)
      .padding({ left: 12, right: 12 })
      .justifyContent(FlexAlign.Center)
    }
    .width(250)
    .backgroundColor($r('app.color.white'))
    .borderRadius(5)
    .padding({ left: 17, right: 17, top: 12, bottom: 22 })
  }

  aboutToAppear() {
    //修正,这里要在这里初始化,否则 this.clickMaskClose 不能响应外部变更
    let dialogController = new CustomDialogController({
      builder: MyCustomDialog({
        dialogContent: () => {
          this.buildContent();
        }
      }),
      alignment: this.alignment,
      offset: { dx: 0, dy: this.offsetY },
      // maskColor: this.maskColor,
      autoCancel: this.autoCancel,
      //完全依靠外部样式控制,否则会有宽度限制和默认圆角, 这里需要的就是要自己控制样式
      customStyle: true
    });
    if (this.controller) {
      this.controller.open = () => {
        dialogController.open();
      }
      this.controller.close = () => {
        dialogController.close();
      }
    }
  }
}

3.2. 具体实现,这里是LoadingPop(加载中弹窗)

import MyCustomDialog from './core/MyCustomDialog';
import { MyCustomDialogController } from './core/MyCustomDialogController';
/**
 * @author: hwk
 * @description: 加载动画loading
 * @date: 2024/3/7 14:12
 */
@Component
export default struct LoadingPop {
  controller: MyCustomDialogController = null;
  alignment: DialogAlignment = DialogAlignment.Center; //弹窗位置
  offsetX: number = 0; //上下 偏移量 负数则往上
  offsetY: number = 0; //上下 偏移量 负数则往上
  autoCancel: boolean = false; //点击遮罩层是否关闭弹窗
  //api9不支持 maskColor: ResourceColor = "rgba(0,0,0,0.1)";
  customStyle: true;
  @State angle: number = 0

  build() {
  }

  @Builder buildContent() {
    Column() {
      ImageAnimator()
      Image($r('app.media.loading'))
        .width(50)
        .margin({ top: 16 })
        .rotate({ angle: this.angle })
        .animation({
          duration: 1500,
          curve: Curve.Linear,
          iterations: -1, // 设置-1表示动画无限循环
          playMode: PlayMode.Normal
        })
      Text('加载中...')
        .margin({ top: 16 })
        .fontColor($r('app.color.white'))
        .fontSize(12)
    }
    .width(111)
    .height(111)
    .borderRadius(5)
    .backgroundColor($r('app.color.transparent50'))
  }

  aboutToAppear() {

    //修正,这里要在这里初始化,否则 this.clickMaskClose 不能响应外部变更
    let dialogController = new CustomDialogController({
      builder: MyCustomDialog({
        dialogContent: () => {
          this.buildContent();
        }
      }),
      alignment: this.alignment,
      offset: { dx: 0, dy: this.offsetY },
      autoCancel: this.autoCancel,
      //完全依靠外部样式控制,否则会有宽度限制和默认圆角, 这里需要的就是要自己控制样式
      customStyle: true
    });
    if (this.controller) {
      this.controller.open = () => {
        dialogController.open();

        this.timeoutId = setTimeout(() => {
          this.angle = 360;
        }, 10)
      }
      this.controller.close = () => {
        clearTimeout(this.timeoutId);
        dialogController.close();
      }
    }
  }

  timeoutId: number;
}

4. 调用

  • 9
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值