【HarmonyOS Next】鴻蒙應用實現彈框DialogHub詳解
一、前言
鴻蒙中實現彈框目前官方提供openCustomDialog和CustomDialog兩種模式。推薦前者,詳情見下圖和官網文檔鏈接:
https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V14/arkts-uicontext-custom-dialog-V14
UI強綁定的實現方式API已標注不推薦。推薦使用UI框架層預留掛靠節點的方式,即openCustomDialog。
這兩者的差別詳見【HarmonyOS Next】鴻蒙應用彈框和提示氣泡詳解(一)
除此之外開源三方庫DialogHub可以更加快捷的使用彈窗:
https://gitee.com/hadss/dialoghub
DialogHub底層實現原理為,使用浮層OverlayManager?半模態頁面bindSheet來實現彈框。
可以達到我們在傳統Android和IOS開發中,彈框與頁面生命周期綁定的效果(頁面隱藏,彈框隱藏。頁面銷毀,彈框銷毀)
DialogHub接口屬性詳細信息如下:
https://gitee.com/hadss/dialoghub/blob/master/docs/Reference.md
二、DialogHub的使用
目前DialogHub還是RC版本,并非Final版本。請謹慎使用。
目前DialogHub可以實現的彈框效果如下:
使用起來很簡單,通過三方庫通過級聯的方式,獲取彈框實例對象,設置彈框的樣式,布局,和彈框上的屬性。甚至連彈框內容模板的設置和數據的更新也通過級聯屬性設置,這個思路不錯。
// 導依賴包之后就可操作DialogHub對象
import {DialogHub
} from "@hadss/dialoghub"
如圖所示,紅框中提供了默認的三種樣式的彈框。以Toast彈框舉例:
showToastTest(){DialogHub.getToast().setContent(wrapBuilder(TextToastBuilder))// 自定義內容 .setConfig(CommonConstant.CUSTOM_SAMPLE_CONFIG)// 持續時間 .setDuration(CommonConstant.DURATION_3000).build().show();}// 布局的內容TextToastBuilder() {Stack() {Text("測試文本").fontColor(Color.Black).fontSize(52)}.padding({ left: 20, right: 20 }).height(100)}
自定義彈框:
this.specifiedLocationDialog = this.specifiedLocationDialog ?? DialogHub.getCustomDialog().setOperableContent(wrapBuilder(SnackbarBuilder), (action: DialogAction) => {let param = new SnackbarParams(() => {action.dismiss()}, this.pageInfos)return param})// DocsDot.setStyle({radius: $r('app.float.custom_template_sample_radius'),shadow: CommonConstant.CUSTOM_SAMPLE_STYLE_SHADOW})// DocsDot.setConfig({dialogBehavior: { isModal: false, passThroughGesture: true },dialogPosition: {alignment: DialogAlignment.Bottom,offset: { dx: 0, dy: $r('app.float.specified_location_offset') }}}).build();this.specifiedLocationDialog.show();
更新彈框內容:
let intervalID: number = -1;let time: number = CommonConstant.TIMED_DIALOG_DURATION;let params: TimeToastParams =new TimeToastParams(CommonConstant.TIMED_DIALOG, time + CommonConstant.TIMED_CLOSED);// DocsCode 5this.intervalsDisappearsDialog = this.intervalsDisappearsDialog ?? DialogHub.getCustomDialog().setContent(wrapBuilder(TimeToastBuilder), params).setStyle({radius: $r('app.float.popup_disappears_intervals_radius'),shadow: CommonConstant.CUSTOM_SAMPLE_STYLE_SHADOW}).setAnimation({ dialogAnimation: AnimationType.UP_DOWN }).setConfig({dialogBehavior: { isModal: false, passThroughGesture: true },dialogPosition: {alignment: DialogAlignment.Top,offset: { dy: $r('app.float.popup_disappears_intervals_offset'), dx: 0 }}}).build();this.intervalsDisappearsDialog.show();intervalID = setInterval(() => {time -= 1;params.content = time + CommonConstant.TIMED_CLOSED;this.intervalsDisappearsDialog?.updateContent(params)if (time <= 0 && intervalID) {this.intervalsDisappearsDialog?.dismiss();clearInterval(intervalID);}}, CommonConstant.DURATION_1000);
三、源碼示例
首先配置依賴:
{"modelVersion": "5.0.0","description": "Please describe the basic information.","dependencies": {"@hadss/dialoghub": "^1.0.0-rc.1"},"devDependencies": {"@ohos/hypium": "1.0.19","@ohos/hamock": "1.0.0"},"dynamicDependencies": {}
}
之后導入包,進行調用:
import { DialogHub } from '@hadss/dialoghub';
import { getContext } from '@ohos.app.ability';
import CommonConstant from '../utils/CommonConstant';// 假設的 TextToastParams 類型
interface TextToastParams {title?: string;
}// TextToastBuilder 構建器函數
export function TextToastBuilder(param: TextToastParams) {Stack() {Text(param?.title ?? CommonConstant.PURE_TEXT).fontColor($r('app.color.item_text_color')).fontSize($r('app.float.font_size_regular'))}.padding({ left: $r('app.float.text_toast_padding'), right: $r('app.float.text_toast_padding') }).height($r('app.float.text_toast_height'))
}// 假設的組件擴展,用于按鈕樣式
(Button)
function superFancyButton() {return this.width(CommonConstant.FULL_LENGTH).height($r('app.float.index_action_height')).margin({ bottom: $r('app.float.index_action_margin') }).fontSize($r('app.float.font_size_medium')).fontWeight(FontWeight.Medium).backgroundColor($r('app.color.base_blue'));
}
struct DialogHubExample {// 獲取 UI 上下文getUIContext() {return getContext();}aboutToAppear(): void {// 初始化 DialogHubDialogHub.init(this.getUIContext());// 開啟日志DialogHub.openLog('DEBUG');// 創建自定義模板DialogHub.createCustomTemplate(CommonConstant.CUSTOM_TEMPLATE_SIMPLE).setContent(wrapBuilder(TextToastBuilder)).setStyle({ backgroundColor: Color.White }).setConfig({ dialogBehavior: { passThroughGesture: true, isModal: false } }).register();}showCustomDialog() {// 顯示自定義模板的彈框DialogHub.show({templateName: CommonConstant.CUSTOM_TEMPLATE_SIMPLE,data: {// 傳遞數據給彈框title: '這是自定義彈框的標題'}});}build() {Column({ space: 20 }) {Button('顯示自定義彈框', { stateEffect: true, type: ButtonType.Capsule }).superFancyButton().onClick(() => {this.showCustomDialog();});}.width('100%').height('100%').padding({ top: 20, bottom: 20, left: 20, right: 20 });}
}