一、自定义弹窗核心机制

  1. 实现原理

    • 使用 @CustomDialog 装饰器声明弹窗组件

    • 通过 CustomDialogController 控制弹窗生命周期

    • 继承自 CommonDialog 类(API 10+)

  2. 与系统弹窗区别

    特性 系统弹窗 (AlertDialog) 自定义弹窗 (CustomDialog)
    UI 控制权 受限 完全自主
    布局复杂度 简单文本/按钮 支持任意 ArkUI 组件
    交互扩展性 基础回调 自定义事件传递

🚀 二、四步实现自定义弹窗

步骤 1:创建弹窗组件
@CustomDialog
struct CustomDialogExample {
  // 控制器必须声明
  controller: CustomDialogController | null = null; 
  
  // 自定义参数(支持动态注入)
  @Prop message: string = '默认提示';

  build() {
    Column() {
      Text(this.message).fontSize(18)
      Button('关闭').onClick(() => {
        this.controller?.close(); // 手动关闭弹窗
      })
    }
    .padding(24)
    .backgroundColor(Color.White)
    .borderRadius(8)
  }
}
步骤 2:初始化控制器
// 在调用页面/组件中
private dialogController: CustomDialogController = new CustomDialogController({
  builder: CustomDialogExample({ 
    message: '自定义内容' // 参数注入
  }),
  alignment: DialogAlignment.Center, // 位置:Top/Center/Bottom
  offset: { dx: 0, dy: -20 },       // 位置偏移
  autoCancel: true,                  // 点击遮罩层关闭
  customStyle: true                  // 禁用默认样式
});
步骤 3:控制弹窗生命周期
方法 作用 使用场景
open() 显示弹窗 按钮点击触发
close() 关闭弹窗 弹窗内部操作关闭
position() 动态设置位置 (API 10+) 响应屏幕旋转
步骤 4:事件通信
// 1. 定义回调函数
@State dialogResult: string = '';

// 2. 弹窗内触发事件
Button('确认').onClick(() => {
  AppStorage.setOrCreate('dialogEvent', 'confirmed');
  this.controller?.close();
})

// 3. 父组件监听
.onAppear(() => {
  AppStorage.Sub('dialogEvent', (val) => {
    this.dialogResult = val;
  })
})

⚠️ 三、关键注意事项

  1. 样式覆盖

    • 设置 customStyle: true 禁用系统圆角/背景

    • 推荐手动添加阴影:.shadow({ radius: 10, color: '#1A000000' })

  2. 动画实现

    // 入场动画示例
    .transition({ type: TransitionType.Insert, scale: { x: 0, y: 0 } })
    .transitionOptions({ duration: 300, curve: Curve.EaseOut })
  3. 内存管理

    • 页面销毁时需调用 dialogController.destroy()

    • 避免在 aboutToAppear 中创建控制器

  4. 多屏适配

    // 响应式位置调整
    .onAreaChange((oldVal, newVal) => {
      this.dialogController.position({
        dx: newVal.width * 0.1, 
        dy: newVal.height * 0.2
      })
    })


💡 四、进阶实践技巧

  1. 组合式弹窗
    封装可复用的弹窗模板:

    // 构建基础弹窗框架
    @Builder
    function DialogFrame(title: string, content: () => void) {
      Column() {
        Text(title).fontSize(20)
        content()
      }
    }
  2. 动态内容注入
    通过控制器更新内容:

    // 更新弹窗内容
    this.dialogController.updateBuilder(
      CustomDialogExample({ message: '新内容' })
    );
  3. 嵌套滚动支持
    在弹窗内使用 Scroll 组件:

    Scroll() {
      ForEach(items, (item) => {
        ListItem(item.name)
      })
    }
    .height('60%') // 必须限制高度

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐