HarmonyOS promptAction.openCustomDialog外部代理UI实现问题

在做自定义弹窗实现时,往往部分弹窗内部UI内容需要外部实现,但是DialogOptions不能传递@BuilderParam类型参数,代码如下:

import { ComponentContent, promptAction } from '@kit.ArkUI'

@Builder
export function buildCustomDialog(options: promptAction.BaseDialogOptions) {
  MyCustomDialog({ options: options })
}

@CustomDialog
export struct MyCustomDialog {
  controller?: CustomDialogController
  options?: promptAction.BaseDialogOptions
  @BuilderParam builder: () => void = this.defaultBuilder // 这个参数如何传递过来?

  build() {
    Column() {
      this.builder()
    }
    .backgroundColor(Color.Blue)
  }

  @Builder
  defaultBuilder() {
    Text('默认弹窗内容')
      .width('100%')
      .height(150)
      .fontColor(Color.White)
  }
}

@Entry
@Component
struct Index {
  build() {
    Column() {
      Text('点击打开一个弹窗')
        .height(88)
        .width('100%')
        .backgroundColor('#fafafc')
        .onClick(() => {
          const options: promptAction.BaseDialogOptions = {}
          const content = new ComponentContent(this.getUIContext(), wrapBuilder(buildCustomDialog), options)
          this.getUIContext().getPromptAction().openCustomDialog(content)
        })
    }
    .height('100%')
    .width('100%')
  }
}
HarmonyOS
2024-12-25 13:45:13
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
shlp

目前规格如此,可通过promptAction.openCustomDialog创建CustomDialog的方式刷新弹窗内容,点击页面中的两个的hello文本,会触发点击事件实现弹窗内容的动态刷新。参考示例如下:

import { UIContext } from '@ohos.arkui.UIContext';
import { ComponentContent } from "@ohos.arkui.node";
import { BusinessError } from '@ohos.base';

export class myTestClass {
  ctx: UIContext;
  myNode: ComponentContent<Object>;
  params: Object
  options: Object

  constructor(context: UIContext, obj?: Object) {
    this.ctx = context;
    this.params = obj
  }

  setCtx(context) {
    this.ctx = context;
  }

  getCtx() {
    return this.ctx;
  }

  setBuilderNode(node: ComponentContent<Object>) {
    this.myNode = node;
  }

  setOptions(opts: Object) {
    this.options = opts
  }

  openTestDialog() {
    console.error("tag1----" + this.ctx);
    if (this.myNode != null) {
      this.ctx.getPromptAction()
        .openCustomDialog(this.myNode, this.options)
        .then(() => {
          console.info('tag------openCustomDialog complete!!!');
        })
        .catch((error: BusinessError) => {
          let message = (error as BusinessError).message
          let code = (error as BusinessError).code
          console.error(`tag------openCustomDialog args error code is ${code}, message is ${message}`);
        })
    }
  }

  updateTestDialog(params: Object) {
    this.myNode.update(params)
  }

  updateDialogOptions(node: ComponentContent<Object>, opts: Object) {
    if (node != null) {
      this.ctx.getPromptAction()
        .updateCustomDialog(node, opts)
        .then(() => {
          console.info('tag------updateCustomDialog complete!!!');
        })
        .catch((error: BusinessError) => {
          let message = (error as BusinessError).message
          let code = (error as BusinessError).code
          console.error(`tag------updateCustomDialog args error code is ${code}, message is ${message}`);
        })
    }
  }

  closeTestDialog(node: ComponentContent<Object>) {
    if (node != null) {
      this.ctx.getPromptAction()
        .closeCustomDialog(node)
        .then(() => {
          console.info('tag------closeCustomDialog complete!!!');
        })
        .catch((error: BusinessError) => {
          let message = (error as BusinessError).message
          let code = (error as BusinessError).code
          console.error(`tag------closeCustomDialog args error code is ${code}, message is ${message}`);
        })
    }
  }
}
import { UIContext } from '@ohos.arkui.UIContext';
import { getMyUiContext } from '../entryability/EntryAbility';
import { myTestClass } from './test';
import { ComponentContent } from "@ohos.arkui.node"
import promptAction from '@ohos.promptAction'
import { BusinessError } from '@ohos.base';

let customDialogId: number = 0

@Builder
function customDialogBuilder() {
  Column() {
    Text('Custom dialog Message').fontSize(10)
    Row() {
      Button("确认").onClick(() => {
        promptAction.closeCustomDialog(customDialogId)
      })
      Blank().width(50)
      Button("取消").onClick(() => {
        promptAction.closeCustomDialog(customDialogId)
      })
    }
    TextInput()
  }.height(200).padding(5).backgroundColor(Color.Yellow)
}

@Builder
function customDialogBuilderE() {
}

class Params {
  text: string = ""
  okCallback: () => void

  constructor(text: string, okCallback: () => void) {
    this.text = text;
    this.okCallback = okCallback
  }
}

@Builder
function buildText(params: Params) {
  Column() {
    Button('sdcbjadsbc').margin(10)
    Text(params.text)
      .fontSize(50)
      .fontWeight(FontWeight.Bold)
      .width(300)
      .height(200)
      .borderRadius(30)
      .onClick(() => {
        params.okCallback()
        console.info('tag------buildText click!!!!');
      })
    // TextInput().width(200)
  }.backgroundColor(Color.Yellow)
  .onClick(() => {
    promptAction.showToast({
      message: "sjkfnjhv bhjfd"
    })
  })
  // .offset({x:0,y:16})
  .rotate({
    x: 0,
    y: 0,
    z: 1,
    centerX: '50%',
    centerY: '50%',
    angle: 300
  })
}

function clickAction(testCallback: () => void, message: string, newTestCallback: () => void) {
  let ctx: UIContext | null = getMyUiContext()
  let contentNode = new ComponentContent(ctx as UIContext, wrapBuilder(buildText), new Params(message, testCallback))
  let ttt: myTestClass = new myTestClass(ctx as UIContext, new Params(message, testCallback))
  if (ctx != null) {
    ttt.setBuilderNode(contentNode);
    ttt.setOptions({
      alignment: DialogAlignment.TopStart,
      // maskRect: { x: 50, y: 200, width: '100%', height: '50%' },
      // maskColor:'rgba(255, 10, 255, 0.5)',
      autoCancel: false,
      // isModel:false,
      // showInSubWindow: true,
      offset: { dx: 0, dy: 50 },
      onWillDismiss: (dismissDialog: DismissDialogAction) => {
        console.info("tag-----reason=" + JSON.stringify(dismissDialog.reason))
        console.info("tag-----dialog onWillDismiss")
        if (dismissDialog.reason == DismissReason.PRESS_BACK) {
          dismissDialog.dismiss()
        }
        if (dismissDialog.reason == DismissReason.TOUCH_OUTSIDE) {
          dismissDialog.dismiss()
        }
      },
      onDidAppear: () => {
        console.info("tag----customDialog:onDidAppear()")
      },
      onDidDisappear: () => {
        console.info("tag----customDialog:onDidDisappear()")
      },
      onWillAppear: () => {
        console.info("tag----customDialog:onWillAppear()")
      },
      onWillDisappear: () => {
        console.info("tag----customDialog:onWillDisappear()")
      },
      transition: TransitionEffect.asymmetric(TransitionEffect.OPACITY
        .animation({ duration: 3000, curve: Curve.Sharp })
        .combine(TransitionEffect.scale({ x: 1.5, y: 1.5 }).animation({ duration: 3000, curve: Curve.Sharp })),
        TransitionEffect.OPACITY.animation({ duration: 100, curve: Curve.Smooth })
          .combine(TransitionEffect.scale({ x: 0.5, y: 0.5 }).animation({ duration: 100, curve: Curve.Smooth })))
    });
    ttt.openTestDialog();
    setTimeout(() => {
      if (contentNode != null) {
        ttt.updateTestDialog(new Params('NEW NEW NEW NEW', newTestCallback));
      }
    }, 2500)
  }
}

@Entry
@Component
struct Index {
  @State message: string = "hello"

  testCallback() {
    console.info('tag-------testCallback!!!')
  }

  newTestCallback() {
    console.info("tag-----dialog newTestCallback!!!!!!");
  }

  build() {
    Row() {
      Column() {
        Column() {
          Text(this.message)
            .fontSize(50)
            .fontWeight(FontWeight.Bold)
            .onClick(() => {
              clickAction(this.testCallback, this.message, this.newTestCallback)
            })
        }
        .width('100%')
        Column() {
          Text(this.message)
            .fontSize(50)
            .fontWeight(FontWeight.Bold)
            .onClick(() => {
              promptAction.openCustomDialog({
                builder: customDialogBuilder.bind(this),
                showInSubWindow: true,
              }).then((dialogId: number) => {
                customDialogId = dialogId
              }).catch((error: BusinessError) => {
                let message = (error as BusinessError).message
                let code = (error as BusinessError).code
                console.error(`tag------promptAction.openCustomDialog args error code is ${code}, message is ${message}`);
              })
            })
        }
        .width('100%')

        Button('AlertDialog Set Duration')
          .onClick(() => {
            AlertDialog.show(
              {
                title: 'AlertDialog 1',
                message: 'Set Animation Duration open 3 second, close 100ms',
                autoCancel: true,
                alignment: DialogAlignment.Top,
                offset: { dx: 0, dy: -20 },
                gridCount: 3,
                transition: TransitionEffect.asymmetric(TransitionEffect.OPACITY
                  .animation({ duration: 3000, curve: Curve.Sharp })
                  .combine(TransitionEffect.scale({ x: 1.5, y: 1.5 })
                    .animation({ duration: 3000, curve: Curve.Sharp })),
                  TransitionEffect.OPACITY.animation({ duration: 100, curve: Curve.Smooth })
                    .combine(TransitionEffect.scale({ x: 0.5, y: 0.5 })
                      .animation({ duration: 100, curve: Curve.Smooth }))),
                confirm: {
                  value: 'button',
                  action: () => {
                    console.info('Button-clicking callback')
                  }
                },
                cancel: () => {
                  console.info('Closed callbacks')
                }
              }
            )
          })
        TextInput().width(400).margin({ top: 300 })
      }
      .width('100%')
      .height('100%')
    }
    .height('100%')
  }
}

@BuilderParam装饰的方法只能被自定义构建函数(@Builder装饰的方法)初始化。

@BuilderParam装饰的方法可以是有参数和无参数的两种形式,需与指向的@Builder方法类型匹配。

@BuilderParam装饰的方法类型需要和@Builder方法类型一致。

具体参考链接:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-builderparam-0000001820999553

分享
微博
QQ
微信
回复
2024-12-25 15:49:54
相关问题
HarmonyOS promptAction.openCustomDialog问题
159浏览 • 1回复 待解决
promptAction.openCustomDialog 全局弹窗
798浏览 • 1回复 待解决
promptAction.openCustomDialog 自定义弹窗
532浏览 • 1回复 待解决