HarmonyOS实战:首页多弹窗顺序弹出终极解决方案

背景

随着应用软件功能的不断增加,应用程序软件首页成为弹窗的重灾区,不仅有升级弹窗,还有积分弹窗,签到,引导等各种弹窗。为了彻底解弹窗问题,本文将使用设计模式解决这个痛点。

设计模式

本方案采用责任链设计模式和建造者设计模式,通过将不同的弹窗添加到弹窗处理类,然后按显示顺序。

实现方案

先定义基础弹窗接口 DialogIntercept,统一弹窗的行为。intercept() 方法用于执行下一个弹窗。show ()方法用于判断当前弹窗是否显示,这里同时支持异步接口请求返回的判断。

export interface DialogIntercept{


  intercept(dialogChain:DialogChain):void

  show():boolean |Promise<boolean>

}

提供一个弹窗处理类DialogChain,用于处理多个弹窗的执行逻辑,将弹窗依次添加到 chainList 中保存,然后执行proceed()方法开始显示弹窗,同时提供一个proceedNext() 方法用于直接跳过当前弹窗,由于代码较多,此处省略了部分代码。

/**

* 处理弹窗执行

*/

export class DialogChain {

  private index: number = 0

  private chainList: ArrayList<DialogIntercept> = new ArrayList()

  addIntercept(dialogIntercept: DialogIntercept): DialogChain {

    if (!this.chainList.has(dialogIntercept)) {

      this.chainList.add(dialogIntercept)

    }

    return this

  }

  /**

  * 不执行当前弹窗,可以直接跳过

  */

  proceedNext() {

    ++this.index

    this.proceed()

  }

  /**

  * 调用继续执行下一步

  */

  proceed() {

    if (this.index >= 0 && this.index < this.chainList.length) {

      let dialogIntercept = this.chainList[this.index]

      let show = dialogIntercept.show()

      if (typeof show === 'boolean' && show) { {

        ..........

      } else if (show instanceof Promise) {

      ...........

      } else {

      ........

      }

    } else {

      this.index = 0

    }

  }

}

自定义弹窗实现DialogIntercept 接口,通过show()方法的返回值决定当前弹窗是否弹出,如签到弹窗肯定是每天弹出,可以根据条件 直接返还 true。或者是礼物弹窗,当接口查询到还有是否有未领取的礼物来决定弹窗的是否弹出。这里简单测试一下。

分别定义弹窗 DialogA,DialogB,DialogC,实现接口DialogIntercept。

export class DialogA implements DialogIntercept {

  uiContext: UIContext

  contentNode?: ComponentContent<DialogParams>

  promptAction?: PromptAction

  constructor(uiContext: UIContext) {

    this.uiContext = uiContext;

    this.promptAction = this.uiContext.getPromptAction();

  }

  intercept(dialogChain: DialogChain): void {

    let params = new DialogParams()

    params.callBack = () => {

      this.promptAction?.closeCustomDialog(this.contentNode)

      dialogChain.proceed()

    }

    // UI展示的Node

    this.contentNode = new ComponentContent(this.uiContext, wrapBuilder(DialogABuild), params);

    // 打开弹窗

    this.promptAction?.openCustomDialog(

      this.contentNode,

      {

        isModal: true,

        autoCancel: true,

        alignment: DialogAlignment.Center

      }

    )

  }

  show(): boolean | Promise<boolean> {

    return true

  }

}

@Builder

function DialogABuild(params: DialogParams) {

  // 封装后的UI

  DialogView({ eventModel: params,content:"恭喜您,获得300万积分,请及时领取!",confirmBtnContent:"领取",cancelBtnContent:"取消" })

}

export class DialogParams {

  callBack = () => {

  }

}

将三个弹窗添加到弹窗管理类,然后依次执行弹窗。

  private dialogChain = new DialogChain()

this.dialogChain

      .addIntercept(new DialogA(this.getUIContext()))

      .addIntercept(new DialogB(this.getUIContext()))

      .addIntercept(new DialogC(this.getUIContext()))

//开始执行弹窗

this.dialogChain.proceed()

实现效果如下:


©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容