HarmonyOS 鸿蒙Next中使用自定义弹窗的实现

发布于 1周前 作者 h691938207 来自 鸿蒙OS

HarmonyOS 鸿蒙Next中使用自定义弹窗的实现
<markdown _ngcontent-pjq-c147="" class="markdownPreContainer">

自定义弹窗(CustomDialog)可用于广告、中奖、警告、软件更新等与用户交互响应操作。开发者可以通过 CustomDialogController 类显示自定义弹窗。具体用法请参考自定义弹窗。

在应用的使用和开发中,弹窗是一个很常见的场景,自定义弹窗又因为极高的自由度得以广泛应用。本文以橘子购物中一个应用更新提示的弹窗介绍 OpenHarmony 的自定义弹窗。

简单使用

1.1 创建自定义弹窗

使用 [@CustomDialog](/user/CustomDialog) 装饰器装饰自定义弹窗。[@CustomDialog](/user/CustomDialog) 装饰器用于装饰自定义弹框,此装饰器内进行自定义内容(也就是弹框内容)。

深色代码主题
复制
[@CustomDialog](/user/CustomDialog)
struct CustomDialogExample {
  [@Link](/user/Link) textValue: string
  [@Link](/user/Link) inputValue: string
  controller: CustomDialogController
  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(() => { this.controller.close() this.cancel() }).backgroundColor(0xffffff).fontColor(Color.Black) Button(‘confirm’) .onClick(() => { this.inputValue = this.textValue this.controller.close() this.confirm() }).backgroundColor(0xffffff).fontColor(Color.Red) }.margin({ bottom: 10 }) } } }

1.2 创建构造器,与装饰器呼应相连

在创建好自定义弹窗之后,我们 new 出来它的对象,类型是 CustomDialogController

深色代码主题
复制
dialogController: CustomDialogController = new CustomDialogController({
  builder: CustomDialogExample({
    cancel: this.onCancel,
    confirm: this.onAccept,
    textValue: $textValue,
    inputValue: $inputValue
  }),
  cancel: this.existApp,
  autoCancel: true,
  alignment: DialogAlignment.Bottom,
  offset: { dx: 0, dy: -20 },
  gridCount: 4,
  customStyle: false,
})

// 在自定义组件即将析构销毁时将dialogController删除和置空 aboutToDisappear() { delete this.dialogController; // 删除dialogController this.dialogController = undefined; // 将dialogController置空 }

onCancel() { console.info(‘Callback when the first button is clicked’) }

onAccept() { console.info(‘Callback when the second button is clicked’) }

existApp() { console.info(‘Click the callback in the blank area’) }

升级弹窗界面示例

定义 CustomDialogController

首先,我们需要定义一个 CustomDialogController

深色代码主题
复制
UpdateDialogController: CustomDialogController = new CustomDialogController({
  builder: UpdateDialog(),
  customStyle: true,
})

这个 CustomDialogController 就代表弹窗,UpdateDialog() 是弹窗的具体实现,customStyletrue 表示弹窗样式可以自定义。

设置调用时机

在这个场景中,我们想要每次打开应用的时候弹窗,其他时候不弹窗,我们需要在首页组件的 aboutToAppear 中加入以下代码:

深色代码主题
复制
aboutToAppear() {
  if(AppStorage.Get('nowIndex') === undefined || AppStorage.Get('nowIndex') === 0) {
    this.UpdateDialogController.open()
  }
}

aboutToAppear 函数的调用时机是创建自定义组件的新实例后,执行其 build() 函数之前,所以在首页组件的 aboutToAppear 中加入 CustomDialogController 的打开逻辑可使弹窗仅在应用打开的时候触发。

实现 builder 实例

实现实例可以直接在 builder 后面直接实现,也可以定义在其他文件中,然后通过调用的方式获取,本文以调用方式实现。

实例组件的定义前需加 export 才能暴露出去:

深色代码主题
复制
export struct UpdateDialog {}

@CustomDialog export struct UpdateDialog { @State currentVersion: string = ‘’ @State richTextData: string = ‘’ @State lastVersion: string = ‘’ @State updateContent: string = ‘’ private context?: AbilityContext private customDialogController?: CustomDialogController

async aboutToAppear() { this.context = getContext(this) as AbilityContext this.richTextData = await dialogFeature.getRichTextData(this.context) Logger.info(TAG, this.richTextData = <span class="hljs-subst">${<span class="hljs-variable language_">this</span>.richTextData}</span>) await this.getData() }

async getData() { try { this.currentVersion = await dialogFeature.getCurrentVersion() let requestResponseContent: RequestResponseContent = await dialogFeature.getLastVersion() if (requestResponseContent.content === null || requestResponseContent.content === undefined) { return } this.updateContent = requestResponseContent.content if (requestResponseContent.versionName === null || requestResponseContent.versionName === undefined) { return } this.lastVersion = requestResponseContent.versionName } catch (err) { Logger.info(TAG, getApplicationVersion is fail) } }

// 其他代码实现… }

弹窗具体实现

自定义弹窗的实现就是在原页面的基础上再加一层页面,页面内容自定义。

弹窗页面我们可以通过 Stack 组件实现,Stack 组件会使容器内的子组件堆叠布局,使用 Stack 的好处是可以添加一层遮罩效果。

深色代码主题
复制
build() {
  Stack() {
    // mask 遮罩层
    Column()
      .width('100%')
      .height('100%')
      .backgroundColor('#000000')
      .opacity(0.4)
<span class="hljs-title class_">Column</span>() {
  <span class="hljs-title class_">Stack</span>({ <span class="hljs-attr">alignContent</span>: <span class="hljs-title class_">Alignment</span>.<span class="hljs-property">TopStart</span> }) {
    <span class="hljs-title class_">Text</span>($r(<span class="hljs-string">'app.string.update_title'</span>))
      .<span class="hljs-title function_">fontSize</span>(<span class="hljs-number">30</span>)
      .<span class="hljs-title function_">fontColor</span>(<span class="hljs-string">'#FFFFFF'</span>)
      .<span class="hljs-title function_">fontWeight</span>(<span class="hljs-number">500</span>)
      .<span class="hljs-title function_">margin</span>({ <span class="hljs-attr">top</span>: <span class="hljs-number">70</span>, <span class="hljs-attr">left</span>: <span class="hljs-number">76</span> })

    <span class="hljs-title class_">Text</span>(<span class="hljs-string">`V<span class="hljs-subst">${(<span class="hljs-variable language_">this</span>.lastVersion || updateData.versionName)}</span>`</span>)
      .<span class="hljs-title function_">fontSize</span>(<span class="hljs-number">16</span>)
      .<span class="hljs-title function_">backgroundColor</span>(<span class="hljs-string">'#FFFFFF'</span>)
      .<span class="hljs-title function_">textAlign</span>(<span class="hljs-title class_">TextAlign</span>.<span class="hljs-property">Center</span>)
      .<span class="hljs-title function_">fontColor</span>(<span class="hljs-string">'#E9304E'</span>)
      .<span class="hljs-title function_">borderRadius</span>(<span class="hljs-number">20</span>)
      .<span class="hljs-title function_">width</span>(<span class="hljs-number">80</span>)
      .<span class="hljs-title function_">aspectRatio</span>(<span class="hljs-number">2.8</span>)
      .<span class="hljs-title function_">margin</span>({ <span class="hljs-attr">top</span>: <span class="hljs-number">110</span>, <span class="hljs-attr">left</span>: <span class="hljs-number">76</span> })

    <span class="hljs-title class_">Column</span>() {
      <span class="hljs-comment">// 富文本容器</span>
      <span class="hljs-title class_">Scroll</span>() {
        <span class="hljs-title class_">Column</span>() {
          <span class="hljs-keyword">if</span> (<span class="hljs-variable language_">this</span>.<span class="hljs-property">richTextData</span>) {
            <span class="hljs-title class_">RichText</span>((<span class="hljs-variable language_">this</span>.<span class="hljs-property">updateContent</span> || <span class="hljs-variable language_">this</span>.<span class="hljs-property">richTextData</span>))
              .<span class="hljs-title function_">width</span>(<span class="hljs-string">'100%'</span>)
              .<span class="hljs-title function_">height</span>(<span class="hljs-string">'100%'</span>)
          }
        }
        .<span class="hljs-title function_">width</span>(<span class="hljs-string">'100%'</span>)
      }
      .<span class="hljs-title function_">height</span>(<span class="hljs-number">200</span>)

      <span class="hljs-title class_">Row</span>() {
        <span class="hljs-title class_">Button</span>($r(<span class="hljs-string">'app.string.cancel'</span>))
          .<span class="hljs-title function_">commonButtonStyle</span>()
          .<span class="hljs-title function_">fontSize</span>(<span class="hljs-number">20</span>)
          .<span class="hljs-title function_">margin</span>({ <span class="hljs-attr">left</span>: <span class="hljs-number">10</span> })
          .<span class="hljs-title function_">fontColor</span>(<span class="hljs-string">'#E92F4F'</span>)
          .<span class="hljs-title function_">backgroundColor</span>(<span class="hljs-string">'rgba(0,0,0,0.05)'</span>)
          .<span class="hljs-title function_">margin</span>({ <span class="hljs-attr">right</span>: <span class="hljs-number">10</span> })
          .<span class="hljs-title function_">onClick</span>(<span class="hljs-function">() =&gt;</span> {
            <span class="hljs-variable language_">this</span>.<span class="hljs-property">customDialogController</span>.<span class="hljs-title function_">close</span>()
          })
          .<span class="hljs-title function_">key</span>(<span class="hljs-string">"cancel"</span>)

        <span class="hljs-title class_">Button</span>($r(<span class="hljs-string">'app.string.update_now'</span>))
          .<span class="hljs-title function_">commonButtonStyle</span>()
          .<span class="hljs-title function_">fontSize</span>(<span class="hljs-number">20</span>)
          .<span class="hljs-title function_">margin</span>({ <span class="hljs-attr">right</span>: <span class="hljs-number">10</span> })
          .<span class="hljs-title function_">fontColor</span>(<span class="hljs-string">'#FFFFFF'</span>)
          .<span class="hljs-title function_">backgroundColor</span>(<span class="hljs-string">'#E92F4F'</span>)
          .<span class="hljs-title function_">margin</span>({ <span class="hljs-attr">left</span>: <span class="hljs-number">10</span> })
          .<span class="hljs-title function_">onClick</span>(<span class="hljs-function">() =&gt;</span> {
            <span class="hljs-variable language_">this</span>.<span class="hljs-property">customDialogController</span>.<span class="hljs-title function_">close</span>()
            <span class="hljs-comment">// 在这里可以添加更新逻辑</span>
          })
          .<span class="hljs-title function_">key</span>(<span class="hljs-string">"Now"</span>)
      }
      .<span class="hljs-title function_">margin</span>({ <span class="hljs-attr">top</span>: <span class="hljs-number">30</span> })
    }
    .<span class="hljs-title function_">width</span>(<span class="hljs-string">'100%'</span>)
    .<span class="hljs-title function_">padding</span>({ <span class="hljs-attr">left</span>: <span class="hljs-number">25</span>, <span class="hljs-attr">right</span>: <span class="hljs-number">25</span> })
    .<span class="hljs-title function_">margin</span>({ <span class="hljs-attr">top</span>: <span class="hljs-number">230</span> })
  }
  .<span class="hljs-title function_">height</span>(<span class="hljs-number">600</span>)
  .<span class="hljs-title function_">width</span>(<span class="hljs-string">'100%'</span>)
  .<span class="hljs-title function_">backgroundImage</span>($r(<span class="hljs-string">'app.media.update'</span>), <span class="hljs-title class_">ImageRepeat</span>.<span class="hljs-property">NoRepeat</span>)
  .<span class="hljs-title function_">backgroundImageSize</span>(<span class="hljs-title class_">ImageSize</span>.<span class="hljs-property">Contain</span>)
}
.<span class="hljs-title function_">width</span>(<span class="hljs-number">480</span>)
.<span class="hljs-title function_">padding</span>({ <span class="hljs-attr">left</span>: <span class="hljs-number">16</span>, <span class="hljs-attr">right</span>: <span class="hljs-number">16</span> })

} .width(‘100%’) .height(‘100%’) }

注意事项

需要注意的是,需要在取消按钮的调用函数中关闭弹窗,具体代码如下:

深色代码主题
复制
Button($r('app.string.cancel'))
  .onClick(() => {
    this.customDialogController.close()
  })

参考

本文供稿:刘家辉 (JaysonLiu3) - Gitee.com

本例参考的官方文档:


</markdown>

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

1 回复

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


在HarmonyOS 鸿蒙Next中,实现自定义弹窗可以通过创建自定义的AbilitySlice或者利用Dialog组件来完成。以下是基于Dialog组件的简要实现步骤:

  1. 定义自定义布局: 在resources/layout目录下创建一个XML文件,定义弹窗的布局。例如custom_dialog_layout.xml,其中可以包含文本、按钮等控件。

  2. 创建Dialog对象: 在需要显示弹窗的页面中,通过LayoutInflater加载自定义布局,并创建CommonDialog对象。

    LayoutInflater inflater = LayoutInflater.from(this);
    View dialogView = inflater.inflate(R.layout.custom_dialog_layout, null);
    CommonDialog dialog = new CommonDialog(this, dialogView);
    
  3. 设置Dialog属性: 可以设置对话框的标题、是否可取消等属性。

    dialog.setTitle("自定义弹窗标题");
    dialog.setCancelable(true);
    
  4. 显示Dialog: 调用show()方法显示对话框。

    dialog.show();
    
  5. 处理事件: 如果自定义布局中有按钮等控件,可以通过findViewById获取并设置点击事件。

如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html

回到顶部