HarmonyOS鸿蒙Next中全局@Builder function时,组件无渲染问题,求大佬帮忙解决

HarmonyOS鸿蒙Next中全局@Builder function时,组件无渲染问题,求大佬帮忙解决

自定义弹窗基类

import { ComponentContent, PromptAction, UIContext } from "@kit.ArkUI"
import { BusinessError } from "@kit.BasicServicesKit"
import { JSON } from "@kit.ArkTS"

export interface DialogButtonOptions {
  text?: ResourceStr
  fontColor?: ResourceStr
  onClick?: () => void
}

export interface BaseOptions {
  autoCancel?: boolean
  message?: ResourceStr
  onDismiss?: () => void
}

export abstract class BaseDialog<T extends BaseOptions> {
  node: ComponentContent<T> | null = null
  prompt: PromptAction | null = null

  protected abstract withCompContent(uiContext: UIContext, options: T): ComponentContent<T>

  protected openDialog(uiContext: UIContext, options: T) {
    this.prompt = uiContext.getPromptAction()
    this.node = this.withCompContent(uiContext, options)
    this.prompt.openCustomDialog(this.node, {
      autoCancel: options.autoCancel ?? false,
      onWillDismiss: (action) => {
        if (options.autoCancel === true) {
          action.dismiss()
        }
      },
      onWillDisappear: () => {
        if (options.onDismiss) {
          options.onDismiss()
        }
      }
    })
  }

  openOptions(uiContext: UIContext | undefined | null, options: T) {
    if (uiContext) {
      this.openDialog(uiContext, options)
    }
  }

  close() {
    try {
      if (this.node && this.prompt) {
        this.prompt.closeCustomDialog(this.node)
      }
    }
    catch (error1) {
      try {
        let message = (error1 as BusinessError).message
        let code = (error1 as BusinessError).code
        console.error(`Close loading dialog args error1 code is ${code}, message is ${message}`)
      }
      catch (error2) {
        console.error(`Close loading dialog args error1 code is ${JSON.stringify(error1)}`)
        console.error(`Close loading dialog args error2 code is ${JSON.stringify(error2)}`)
      }
    }
    finally {
      this.node = null
      this.prompt = null
    }
  }
}

export function dialogPadding(): Length | Padding | LocalizedPadding {
  return {
    left: 16,
    right: 16,
    top: 24,
    bottom: 20
  }
}

自定义通用弹窗

import { ComponentContent, UIContext } from "@kit.ArkUI"
import { BaseDialog, BaseOptions, DialogButtonOptions, dialogPadding } from "./BaseDialog"

export interface CommonOptions extends BaseOptions {
  title?: ResourceStr
  cancelOptions?: DialogButtonOptions
  confirmOptions?: DialogButtonOptions
}

export class CommonDialog extends BaseDialog<CommonOptions> {
  protected withCompContent(uiContext: UIContext, options: CommonOptions): ComponentContent<CommonOptions> {
    return new ComponentContent<BaseOptions>(uiContext, wrapBuilder(buildDialog), options, { nestingBuilderSupported: false })
  }
}

[@Builder](/user/Builder)
function buildDialog(params: CommonOptions) {
  Column({ space: 16 }) {
    if (params.title) {
      Text(params.title)
        .fontSize(18)
        .fontWeight(FontWeight.Bold)
    }
    if (params.message) {
      Text(params.message)
        .fontColor("#191919")
    }
    Row() {
      if (params.confirmOptions && params.cancelOptions) {
        cancelBuilder(params)
        Text("|").margin({ left: 8, right: 8 })
        buttonBuilder(params.confirmOptions) // buttonBuilder 调用无组件输出,只能调用 confirmBuilder
      }
      else {
        if (params.cancelOptions) {
          cancelBuilder(params)
        }
        if (params.confirmOptions) {
          // confirmBuilder(params)
          buttonBuilder(params.confirmOptions) // buttonBuilder 调用无组件输出,只能调用 confirmBuilder
        }
      }
    }
  }
  .padding(dialogPadding())
  .backgroundColor(Color.White)
  .flexShrink(1)
  .borderRadius(8)
  .width('88%')
  .constraintSize({ maxWidth: 300 })
  .justifyContent(FlexAlign.Center)
}

[@Builder](/user/Builder)
function confirmBuilder(params: CommonOptions) {
  Text(params.confirmOptions!!.text)
    .fontColor(params.confirmOptions!!.fontColor)
    .fontWeight(FontWeight.Bold)
    .onClick(params.confirmOptions!!.onClick)
    .layoutWeight(1)
    .textAlign(TextAlign.Center)
}

[@Builder](/user/Builder)
function buttonBuilder(params: DialogButtonOptions | undefined) {
  Text(params!!.text)
    .fontColor(params!!.fontColor)
    .fontWeight(FontWeight.Bold)
    .onClick(params!!.onClick)
    .layoutWeight(1)
    .backgroundColor(Color.Pink)
    .textAlign(TextAlign.Center)
}

[@Builder](/user/Builder)
function cancelBuilder(params: CommonOptions) {
  Text(params.cancelOptions!!.text)
    .fontColor(params.cancelOptions!!.fontColor)
    .fontWeight(FontWeight.Bold)
    .onClick(params.cancelOptions!!.onClick)
    .textAlign(TextAlign.Center)
    .layoutWeight(1)
}

调用代码如下:

let dialog = new CommonDialog()
dialog.openOptions(this.getUIContext(), {
  autoCancel: true,
  title: "确定重启吗?",
  message: `点击确定将会进行重启App`,
  cancelOptions: {
    text: "取消",
    fontColor: "#1658D9",
    onClick: () => {
      dialog.close()
    }
  },
  confirmOptions: {
    text: "确定",
    fontColor: "#59BB6B",
    onClick: () => {
      dialog.close()
      PasteUtils.copyTextAndToast(DeveloperConfig.WE_CHAT_ID, "复制成功")
    }
  }
})

在通用弹窗里面,因为按钮样式是通用的,所以我准备封装复用,然后发现封装后的 buttonBuilder组件没有渲染出来。传入CommonOptions的参数可以渲染,但是传入CommonOptions.ButtonDialogOptions的参数就失败了,求姐 ~

开发环境是API15,Mate60Pro。 DevEco Studio 5.0.3 Release

Build #DS-233.14475.28.36.5090300

Build Version: 5.0.9.300, built on March 13, 2025

Runtime version: 17.0.12+1-b1087.25 amd64

VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o.

Windows 11.0

GC: G1 Young Generation, G1 Old Generation

Memory: 4026M

Cores: 22

Registry:

idea.plugins.compatible.build=IC-233.14475.28

Non-Bundled Plugins:

com.intellij.ideolog (222.3.2.0)

String Manipulation (9.15.0)

org.intellij.gitee (2023.3.4)


更多关于HarmonyOS鸿蒙Next中全局@Builder function时,组件无渲染问题,求大佬帮忙解决的实战教程也可以访问 https://www.itying.com/category-93-b0.html

2 回复

在HarmonyOS鸿蒙Next中,使用全局@Builder函数时,如果组件无渲染,可能是由于以下原因:

  1. 作用域问题:确保@Builder函数在正确的作用域内被调用。如果@Builder函数定义在某个组件内部,但在其他组件中调用,可能会导致无法渲染。

  2. 状态管理:如果@Builder函数依赖于某些状态变量,确保这些状态变量在渲染时已经正确初始化或更新。状态未更新可能导致组件不渲染。

  3. 生命周期问题:检查@Builder函数的调用时机,确保它在组件的生命周期内被正确调用。例如,在onPageShowonPageReady等生命周期回调中调用@Builder函数。

  4. 组件树结构:确保@Builder函数返回的组件被正确添加到组件树中。如果组件未正确挂载到父组件,可能会导致无渲染。

  5. 样式或布局问题:检查@Builder函数返回的组件是否有正确的样式或布局设置。例如,宽度或高度为0可能导致组件不可见。

  6. 调试信息:使用console.log或调试工具检查@Builder函数是否被正确执行,以及返回的组件是否符合预期。

  7. 版本兼容性:确保使用的HarmonyOS SDK版本与@Builder函数的语法和功能兼容。不同版本可能存在差异。

如果以上问题均已排除,可以尝试将@Builder函数改为局部定义,或在组件内部直接使用@Builder函数,以验证是否是全局定义导致的问题。

更多关于HarmonyOS鸿蒙Next中全局@Builder function时,组件无渲染问题,求大佬帮忙解决的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS鸿蒙Next中,使用全局@Builder函数时,如果组件未渲染,可能是由于以下原因:

  1. 未正确调用:确保在需要的地方正确调用了@Builder函数。
  2. 状态未更新:如果@Builder依赖的状态未更新,组件可能不会重新渲染。确保状态管理正确。
  3. 作用域问题:全局@Builder函数应在正确的作用域内使用,避免作用域冲突。
  4. 组件生命周期:检查组件生命周期,确保在合适的生命周期阶段调用@Builder

建议检查代码逻辑,确保上述问题无误。

回到顶部