HarmonyOS customdialog使用问题

多个子页面使用customdialog,需要在多个子页面中分别去定义controller,是否有更优的使用方法或者是不是有类似工具类的方式统一管理。

图1:红色框代表着子控件,绿色框代表弹窗按钮。

图2:弹窗。

图3:dialog的controller。

当前情况是弹窗的controller分别需要图1的子控件1和子控件2中分别复制一份图3,才能实现在各子页面中触发图2的效果。

HarmonyOS customdialog使用问题-鸿蒙开发者社区

HarmonyOS
2024-10-18 10:14:13
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
zxjiu

有两种方案分别应对需要传参和需要传参的自定义弹窗组件复用:方案一(需要传参):将dialog封装成组件,样式在组件里面写好并维持不变,然后直接在需要弹窗的地方调用自定义组件,demo如下:

//页面一  
import { router } from '@kit.ArkUI';  
@CustomDialog  
struct CustomDialogExample {  
  @Link textValue: string  
  @Link inputValue: string;  
  @Link isOpen: boolean;  
  controller?: CustomDialogController  
  // 若尝试在CustomDialog中传入多个其他的Controller,以实现在CustomDialog中打开另一个或另一些CustomDialog,那么此处需要将指向自己的controller放在所有controller的后面  
  cancel: () => void = () => {  
  }  
  confirm: () => void = () => {  
  }  
  build() {  
    Column() {  
      Text('Change text').fontSize(20).margin({ top: 10, bottom: 10 })  
      TextInput({ placeholder: '', text: this.textValue }).height(60).width('90%')  
        .onChange((value: string) => {  
          this.textValue = value  
        })  
      Text('Whether to change a text?').fontSize(16).margin({ bottom: 10 })  
      Flex({ justifyContent: FlexAlign.SpaceAround }) {  
        Button('cancel')  
          .onClick(() => {  
            if (this.controller != undefined) {  
              this.controller.close()  
              this.cancel();  
              this.isOpen = false;  
            }  
          }).backgroundColor(0xffffff).fontColor(Color.Black)  
        Button('confirm')  
          .onClick(() => {  
            if (this.controller != undefined) {  
              this.inputValue = this.textValue  
              this.controller.close()  
              this.isOpen = false;  
  
              this.confirm()  
            }  
          }).backgroundColor(0xffffff).fontColor(Color.Red)  
      }.margin({ bottom: 10 })  
  
    }.borderRadius(10)  
  
    // 如果需要使用border属性或cornerRadius属性,请和borderRadius属性一起使用。  
  }  
}  
@Component  
export struct CustomDialogChild {  
  @Prop textValue: string = ''  
  @State inputValue: string = 'click me'  
  @Link @Watch('onStateChange') isOpen: boolean;  
  dialogController: CustomDialogController | null = new CustomDialogController({  
    builder: CustomDialogExample({  
      cancel: () => {  
        this.onCancel()  
      },  
      confirm: () => {  
        this.onAccept()  
      },  
      textValue: $textValue,  
      inputValue: $inputValue,  
      isOpen: $isOpen  
    }),  
    cancel: this.exitApp,  
    autoCancel: false,  
    alignment: DialogAlignment.Bottom,  
    offset: { dx: 0, dy: -20 },  
    gridCount: 4,  
    customStyle: false,  
    cornerRadius: 10,  
  })  
  onStateChange() {  
    if (this.isOpen) {  
      this.dialogController?.open()  
    } else {  
      this.dialogController?.close();  
    }  
  }  
  // 在自定义组件即将析构销毁时将dialogControlle置空  
  aboutToDisappear() {  
    this.dialogController = null // 将dialogController置空  
  }  
  onCancel() {  
    console.info('Callback when the first button is clicked')  
  }  
  onAccept() {  
    console.info('Callback when the second button is clicked')  
  }  
  exitApp() {  
    console.info('Click the callback in the blank area')  
  }  
  build() {  
  }  
}  
  
@Entry  
@Component  
struct CustomDialogParent {  
  @State isOpen: boolean = false;  
  build() {  
    Column({ space: 10 }) {  
      Text(String(this.isOpen))  
      CustomDialogChild({  
        textValue: '测试传参',  
        isOpen: this.isOpen  
      });  
      Button('点击打开弹窗').onClick(() => {  
        this.isOpen = true;  
      })  
      Button('点击跳转').onClick(() => {  
        router.pushUrl({  
          url: "pages/Index8"  
        })  
      })  
    }.width('100%').height('100%').justifyContent(FlexAlign.Center)  
  }  
}
//页面二  
import { CustomDialogChild } from './Index7';  
  
@Entry  
@Component  
struct Index8 {  
  @State message: string = 'Hello World';  
  @State ifOpen: boolean = false;  
  
  build() {  
    Column() {  
      Button('打开弹窗').onClick(() => {  
        this.ifOpen = true  
      })  
      CustomDialogChild({  
        textValue: '测试在别的页面传参并打开弹窗',  
        isOpen: this.ifOpen  
      })  
    }  
    .justifyContent(FlexAlign.Center)  
    .height('100%')  
    .width('100%')  
  }  
}

方案二(不需要传参):在A页面创建CustomDialogController对象并保存至全局变量,可以在B页面或其他类内方法通过保存的全局变量,来操作弹窗,不可在使用的地方传递参数,demo如下:

//页面一:  
import { promptAction, router, window } from '@kit.ArkUI';  
@Entry  
@Component  
export struct Index {  
  aDialog: CustomDialogController = new CustomDialogController({  
    builder: ADialog({}),  
  });  
  build() {  
    Column() {  
  
      Button('点我跳转').onClick(() => {  
        //将CustomDialogController对象并保存至全局变量  
        Params.aDialog = this.aDialog;  
        router.pushUrl({  
          url: "pages/Index5"  
        })  
      })  
    }.width('100%')  
    .height("100%")  
    .justifyContent(FlexAlign.Center)  
  }  
}  
/**  
 * 自定义弹窗  
 */  
@CustomDialog  
export struct ADialog {  
  controller: CustomDialogController = new CustomDialogController({  
    builder: ADialog({})  
  })  
  build() {  
    Column() {  
      Text('这是一个弹窗')  
    }.height('70%')  
    .width('100%')  
    .justifyContent(FlexAlign.Center)  
  }  
}  
export class Params {  
  public static aDialog?: CustomDialogController;  
}
//页面二:  
import { Params } from './Index4';  
@Entry  
@Component  
struct Index5 {  
  @State message: string = 'Hello World';  
  @State flag: boolean = false;  
  build() {  
    Column() {  
      Button('点击出现弹窗').onClick(() => {  
        Params.aDialog?.open()  
      })  
    }  
    .justifyContent(FlexAlign.Center)  
    .height('100%')  
    .width('100%')  
  }  
}
分享
微博
QQ
微信
回复
2024-10-18 18:31:16
提问
该提问已有0人参与 ,帮助了0人