鸿蒙对话框封装
前言
鸿蒙也搞了几个月了,感觉自己还是个菜鸡,而且这破环境下,适配新的鸿蒙系统,又不给时间学习,又不给足够的工时,心态有点绷不住。
这篇文章也是个简单的功能,就是封装了一个简单的对话框组件,踩了些坑,记录下。
鸿蒙对话框
在封装对话框前,这里先了解下鸿蒙的对话框如何使用,可以先看官方的参考文档:
其实就是用CustomDialog注解的一个组件,比如像下面这样:
@CustomDialog
struct CustomDialogExample {
controller: CustomDialogController = new CustomDialogController({
builder: CustomDialogExample({}),
})
build() {
Column() {
Text('我是内容')
.fontSize(20)
.margin({ top: 10, bottom: 10 })
}
}
}
简单对话框封装
这里简单写一个带确认和取消的对话框,并能够修改里面内容,获取回调:
/**
* 中间提示的弹框
*/
@CustomDialog
export struct CenterTipPop {
@State param: ControlParam = new ControlParam();
controller: CustomDialogController;
onCancel?: () => void;
@Styles
itemPressedStyle() {
.backgroundColor('#804b8cf1')
}
@Styles
itemNormalStyle() {
.backgroundColor('#4B8CF1')
}
build() {
Column({ space: 0 }) {
Text(this.param.title)
.fontColor(Color.Black)
.fontSize(16)
.maxLines(1)
.height(50)
Text(this.param.content)
.height(100)
.fontColor(Color.Black)
.fontSize(14)
.backgroundColor(Color.Transparent)
.textAlign(TextAlign.Center)
Row() {
if (!this.param.hideLeftBtn) {
Text(this.param.cancelText)
.width('50%')
.height(50)
.fontColor(Color.Black)
.fontSize(16)
.margin({ top: 15 })
.backgroundColor(Color.White)
.textAlign(TextAlign.Center)
.stateStyles({
pressed: this.itemPressedStyle
})
.onClick(() => {
if (this.controller) {
this.controller.close();
}
this.param.onCancel();
})
.borderRadius({
bottomLeft: 15,
})
}
Text(this.param.confirmText)
.width(this.param.hideLeftBtn ? "100%" : '50%')
.height(50)
.fontColor(Color.White)
.fontSize(16)
.margin({ top: 15 })
.backgroundColor("#4B8CF1")
.textAlign(TextAlign.Center)
.stateStyles({
normal: this.itemNormalStyle,
pressed: this.itemPressedStyle
})
.onClick(() => {
if (this.controller) {
this.controller.close();
}
this.param.onConfirm();
})
.borderRadius({
bottomLeft: this.param.hideLeftBtn ? 15 : 0,
bottomRight: 15
})
}
.width('100%')
}
.alignItems(HorizontalAlign.Center)
.width('80%')
.backgroundColor('#f8f8f8')
.borderRadius({
topLeft: 15,
topRight: 15,
bottomLeft: 15,
bottomRight: 15
})
}
}
我这里用了一个对象来保存参数和回调方法:
export class ControlParam {
title: string = "";
content: string = "";
cancelText: string = "";
confirmText: string = "";
hideLeftBtn: boolean = false;
onCancel: () => void = () => {};
onConfirm: () => void = () => {};
}
这里能避过一些坑,比如鸿蒙中,父view的state变量传给子view的prop属性,父view的state变量发生变化,子view的内容也会更新。 但是,如果我们传入的是父view某个state变量的属性,那么这样的动态更新就失效了。
这时候对象的作用就体现出来了,我们直接给子view传入一个state的对象属性,在外部,我们随便修改对象属性,在子view中都会自动更新。
对话框的使用
对话框的使用这里也有大坑,首先这个CustomDialogController的创建一定要在struct里面创建:
// 从其他任意地方来的对象
this.textParam = ...;
// 持有这个CustomDialogController
this.textDialogController = new CustomDialogController({
builder: CenterTipPop(
{
param: this.textParam,
controller: this.textDialogController
}),
cancel: () => {},
autoCancel: true,
alignment: DialogAlignment.Center,
customStyle: true
});
拿到参数对象和CustomDialogController后,我们就能在想要修改对话框效果和显示了:
this.textParam.title = "温馨提示";
this.textParam.content = message;
this.textParam.cancelText = cancelBtnText;
this.textParam.confirmText = confirmBtnText;
this.textParam.hideLeftBtn = false;
this.textParam.onCancel = () => {
resolve("cancel")
};
this.textParam.onConfirm = () => {
resolve("confirm")
};
this.textDialogController.open();
只要页面不销毁,我们持有这个CustomDialogController就能随意弹对话窗了,效果图如下:
小结
简单封装了一个鸿蒙对话框,讲了讲如何创建一个自定义对话框,如何在想要使用的地方更新其中内容、显示、关闭。