鴻蒙系統(HarmonyOS)全域性彈窗實現

安辉發表於2024-09-10

全域性彈窗相對於自定義彈窗有以下優點:

  • 封裝更徹底,一行程式碼就能呼叫
  • 跟元件耦合度低,只需要傳入元件的UIContext物件,不需要跟自定義彈窗一樣需要在元件內部例項化CustomDialogController物件

全域性彈窗是鴻蒙在API 12增加的,PromptAction物件增加了openCustomDialog方法。

程式碼實現

首先建立一個介面,用於引數的傳遞,彈窗內按鈕的點選

interface GlobalDialogParam {
    content:string; //彈窗顯示內容
    onConfirm: () => void //確認按鈕的回撥函式
    onCancel: () => void// 取消按鈕的回撥函式
}

自定義彈窗內容,使用@Builder裝飾器表明該函式將返回一個 UI 元件樹,彈窗內容根據您的需求自己實現。本例中就顯示一個簡單的對話方塊。

@Builder function buildGlobalDialogComponent(param: GlobalDialogParam){
    Column() {
        Text(param.content).fontSize(17).fontColor("#181818")
        .lineHeight(24).margin({
            bottom:29,top:29,left:31,right:31
        })

        Divider().color("#D8D8D8").height(0.5)
        RowSplit() {
            Text("取消").fontSize(17).fontColor("#181818")
            .fontWeight(FontWeight.Bold).onClick(event=>{
                param.onCancel();
            }).textAlign(TextAlign.Center).padding({
                top:15,bottom:15
            }).width('50%')

            Text("確定").fontSize(17).fontColor($r('app.color.mainColor'))
            .fontWeight(FontWeight.Bold).onClick(event=>{
                param.onConfirm();
            }).textAlign(TextAlign.Center).padding({
                top:15,bottom:15
            }).width('50%')
        }
    }.backgroundColor($r('app.color.white')).width('80%').borderRadius(12)
}

在GlobalDialog類中增加兩個靜態方法,用來顯示彈窗跟關閉彈窗,關鍵程式碼都增加來註釋,這裡就不過多解釋了

export class GlobalDialog {
    static contentNode:ComponentContent<GlobalDialogParam>;

    //顯示彈窗
    static show(context: UIContext,dialogParam: GlobalDialogParam){
        //ComponentContent物件有三個引數
        //引數1:UI 上下文
        //引數2:使用 wrapBuilder 包裝 buildGlobalDialogComponent 函式,這個函式用於構建對話方塊的實際內容
        //引數3:傳遞給對話方塊的引數,包含內容文字和按鈕的回撥函式
        GlobalDialog.contentNode = new ComponentContent(context, wrapBuilder(buildGlobalDialogComponent), dialogParam);

        const promptAction = context.getPromptAction()//透過 context 獲取 promptAction,用於操作對話方塊顯示

        //顯示彈窗
        promptAction.openCustomDialog(GlobalDialog.contentNode,{
            alignment: DialogAlignment.Center,//對話方塊在螢幕中央顯示
            autoCancel: false,//點選彈窗外區域是否取消彈窗
        });
    }

    //關閉彈窗
    static close(context: UIContext){
        const promptAction = context.getPromptAction()
        promptAction.closeCustomDialog(GlobalDialog.contentNode)
    }
}

透過以上三個步驟,全域性彈窗的程式碼就封裝好了,接下來在元件中如何呼叫呢?其實程式碼很簡單,呼叫GlobalDialog.show方法顯示彈窗,在確定跟取消按鈕的回撥函式中呼叫GlobalDialog.close取消彈窗。

GlobalDialog.show(this.getUIContext(),{
    content:"您確定要刪除這條記錄嗎?",
    onConfirm:()=>{
        GlobalDialog.close(this.getUIContext())//關閉彈窗
        AppUtil.showToast("確定按鈕點選");
    },
    onCancel:()=>{
        GlobalDialog.close(this.getUIContext())//關閉彈窗
        AppUtil.showToast("取消按鈕點選");
    }
})

效果圖:

延伸閱讀,@Builder 裝飾器

在鴻蒙的 ArkUI 開發中,@Builder 裝飾器是一種用於簡化元件構建的標記,它通常用於函式上,指示該函式返回一個 UI 元件。

@Builder 裝飾器的作用:

  1. 生成UI元件:@Builder 裝飾器標記的函式主要用於構建 UI 元件。它將函式體內定義的 UI 佈局和元件樹返回給呼叫方,以便在應用程式中使用這些元件。
  2. 提高程式碼可讀性和模組化: 透過使用 @Builder,可以把複雜的 UI 構建邏輯封裝到一個函式中,使得程式碼更簡潔和模組化,便於複用。例如,常見的對話方塊、彈窗、複雜元件可以透過這樣的函式構建,並在不同的地方呼叫。
  3. 函式式UI構建: 鴻蒙的 ArkUI 是宣告式 UI 框架,@Builder 提供了一種函式式的 UI 元件建立方式。開發者可以透過定義函式和內部元件來構建介面,並使用該函式返回的元件進行顯示。

原始碼下載

全域性彈窗的程式碼都提交到github上了,這個庫我會一直維護,這個一個鴻蒙API使用案例的工具庫,後續會陸續增加功能以及維護。

https://github.com/ansen666/harmony_tools


掃一掃 關注我的公眾號

相關文章