HarmonyOS鸿蒙Next中CustomDialog自定义弹窗设计

HarmonyOS鸿蒙Next中CustomDialog自定义弹窗设计 在 ArkUI 中,如何使用 @CustomDialog 装饰器创建自定义弹窗?如何控制弹窗的打开和关闭?如何向弹窗传递数据和获取返回值?如何实现弹窗的动画效果?(问题来源项目案例整理:https://github.com/heqiyuan35-creator/HydroQuiz.git

3 回复

@CustomDialog 是 ArkUI 提供的自定义弹窗装饰器,可以创建完全自定义的弹窗组件。

自定义弹窗定义

[@CustomDialog](/user/CustomDialog)
export struct ConfirmDialog {
  controller: CustomDialogController;
  title: string = '提示';
  message: string = '';
  confirmText: string = '确定';
  cancelText: string = '取消';
  onConfirm: () => void = () => {};
  onCancel: () => void = () => {};
  build() {
    Column() {
      Text(this.title)
        .fontSize(18)
        .fontWeight(FontWeight.Bold)
        .margin({ bottom: 16 })
      Text(this.message)
        .fontSize(14)
        .fontColor('#666666')
        .margin({ bottom: 24 })
      Row() {
        Button(this.cancelText)
          .backgroundColor('#F5F5F5')
          .fontColor('#666666')
          .layoutWeight(1)
          .onClick(() => {
            this.onCancel();
            this.controller.close();
          })
        Button(this.confirmText)
          .backgroundColor('#1890FF')
          .fontColor('#FFFFFF')
          .layoutWeight(1)
          .margin({ left: 12 })
          .onClick(() => {
            this.onConfirm();
            this.controller.close();
          })
      }
      .width('100%')
    }
    .padding(24)
    .width('80%')
    .backgroundColor(Color.White)
    .borderRadius(16)
  }
}

使用自定义弹窗

@Entry
@Component
struct MyPage {
  private dialogController: CustomDialogController = new CustomDialogController({
    builder: ConfirmDialog({
      title: '确认删除',
      message: '删除后无法恢复,确定要删除吗?',
      onConfirm: () => this.handleDelete(),
      onCancel: () => console.log('取消')
    }),
    autoCancel: true,
    alignment: DialogAlignment.Center,
    customStyle: true
  });

  private handleDelete(): void {
    // 执行删除逻辑
  }

  build() {
    Button('删除')
      .onClick(() => this.dialogController.open())
  }
}

更多关于HarmonyOS鸿蒙Next中CustomDialog自定义弹窗设计的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS Next中,CustomDialog自定义弹窗通过继承CustomDialogController实现。开发者可在CustomDialog组件内自定义UI布局,使用@CustomDialog装饰器定义弹窗内容。通过controller控制弹窗的显示与隐藏,支持自定义样式、位置和交互行为。事件回调如onWillDismiss可用于处理关闭逻辑。布局使用ArkTS声明式语法,支持动态内容绑定。

在HarmonyOS Next的ArkUI中,使用@CustomDialog装饰器创建自定义弹窗是构建交互界面的核心能力之一。以下是针对你问题的具体实现方案:

1. 创建自定义弹窗

使用@CustomDialog装饰器定义一个弹窗组件,需在struct内实现弹窗内容。

@CustomDialog
struct CustomAlertDialog {
  // 定义接收的参数
  @Prop title: string
  @Prop message: string
  
  // 定义回调函数
  controller: CustomDialogController
  
  build() {
    Column() {
      Text(this.title).fontSize(20).margin(10)
      Text(this.message).fontSize(16).margin(10)
      Button('确定')
        .onClick(() => {
          this.controller.close()
        })
    }
  }
}

2. 控制弹窗打开和关闭

通过CustomDialogController实例控制弹窗状态。

@Entry
@Component
struct DialogExample {
  // 创建控制器
  dialogController: CustomDialogController = new CustomDialogController({
    builder: CustomAlertDialog({
      title: '提示',
      message: '操作成功'
    }),
    cancel: () => {}, // 取消回调
    autoCancel: true // 点击空白处自动关闭
  })
  
  build() {
    Column() {
      Button('打开弹窗')
        .onClick(() => {
          this.dialogController.open() // 打开弹窗
        })
    }
  }
}

3. 数据传递和返回值

传递数据:通过构造函数参数传递

// 定义弹窗时声明参数接口
interface DialogParams {
  title: string
  onConfirm: (result: string) => void
}

@CustomDialog
struct InputDialog {
  @Prop title: string
  @State inputText: string = ''
  private onConfirm: (result: string) => void
  
  controller: CustomDialogController
  
  build() {
    Column() {
      Text(this.title)
      TextInput({ text: this.inputText })
        .onChange((value) => {
          this.inputText = value
        })
      Button('提交')
        .onClick(() => {
          this.onConfirm(this.inputText) // 返回数据
          this.controller.close()
        })
    }
  }
}

使用弹窗并获取返回值

@Entry
@Component
struct MainPage {
  dialogController: CustomDialogController = new CustomDialogController({
    builder: InputDialog({
      title: '请输入',
      onConfirm: (result: string) => {
        // 处理返回结果
        console.log('用户输入:', result)
      }
    })
  })
  
  build() {
    // 页面内容
  }
}

4. 实现动画效果

使用ArkUI的动画API为弹窗添加入场和出场动画:

@CustomDialog
struct AnimatedDialog {
  @State scale: number = 0.5
  @State opacity: number = 0
  
  controller: CustomDialogController
  
  aboutToAppear() {
    // 入场动画
    animateTo({
      duration: 300,
      curve: Curve.EaseOut
    }, () => {
      this.scale = 1
      this.opacity = 1
    })
  }
  
  build() {
    Column() {
      // 弹窗内容
    }
    .scale({ x: this.scale, y: this.scale })
    .opacity(this.opacity)
  }
}

关键要点总结:

  • @CustomDialog装饰器必须修饰struct
  • 通过CustomDialogController管理弹窗生命周期
  • 数据传递使用@Prop装饰器接收参数
  • 返回值通过回调函数或Promise方式处理
  • 动画效果结合animateTo和状态变量实现

这些方法在HydroQuiz项目中可直接应用,特别是需要用户确认或输入的场景。注意弹窗控制器应在父组件中管理,确保正确的生命周期控制。

回到顶部