弹窗是一种模态窗口,通常用来展示用户当前需要的或用户必须关注的信息或操作。在弹出框消失之前,用户无法操作其他界面内容。ArkUI 为我们提供了丰富的弹窗功能,弹窗按照功能可以分为以下两类:
- 确认类:例如警告弹窗 AlertDialog。
- 选择类:包括文本选择弹窗 TextPickerDialog 、日期滑动选择弹窗 DatePickerDialog、时间滑动选择弹窗 TimePickerDialog 等。
可以根据业务场景,选择不同类型的弹窗。
1、什么是自定义弹窗?
自定义弹窗的使用更加灵活,适用于更多的业务场景,在自定义弹窗中您可以自定义弹窗内容,构建更加丰富的弹窗界面。自定义弹窗的界面可以通过装饰器@CustomDialog 定义的组件来实现,然后结合 CustomDialogController 来控制自定义弹窗的显示和隐藏。
2、定义自定义弹窗
@CustomDialog struct CustomDialogExample { // 双向绑定传值 @Prop title: string @Link inputValue: string // 弹窗控制器,控制打开/关闭,必须传入,且名称必须为:controller controller: CustomDialogController // 弹窗中的按钮事件 cancel: () => void confirm: () => void
// 弹窗中的内容描述
build() {
Column() {
Text(this.title || "是否修改文本框内容?")
.fontSize(16)
.margin(24)
.textAlign(TextAlign.Start)
.width("100%")
TextInput({
placeholder: '文本输入框',
text: this.inputValue
})
.height(60)
.width('90%')
.onChange((value: string) => {
this.textValue = value
})
Flex({ justifyContent: FlexAlign.SpaceAround }) {
Button('取消')
.onClick(() => {
this.controller.close()
this.cancel()
}).backgroundColor(0xffffff).fontColor(Color.Black)
Button('确定')
.onClick(() => {
this.controller.close()
this.confirm()
}).backgroundColor(0xffffff).fontColor(Color.Red)
}.margin({ bottom: 10 })
}
}
}
3、使用自定义弹窗
@Entry
@Component
struct Index {
@State title: string = '标题'
@State inputValue: string = '文本框父子组件数据双绑'
// 定义自定义弹窗的Controller,传入参数和回调函数
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
})aboutToDisappear() {
this.dialogController = undefined // 将dialogController置空
}onCancel() {
console.info('点击取消按钮', this.inputValue)
}onAccept() {
console.info('点击确认按钮', this.inputValue)
}
build() {
Column() {
Button('打开自定义弹窗')
.width('60%')
.margin({top:320})
.zIndex(999)
.onClick(()=>{
if (this.dialogController != undefined) {
this.dialogController.open()
}
})
}
.height('100%')
.width('100%')
}
4、一个完整的示例(常用网站选择)
export interface HobbyBean {
label: string;
isChecked: boolean;
}export type DataItemType = { value: string }
@Extend(Button) function dialogButtonStyle() {
.fontSize(16)
.fontColor("#007DFF")
.layoutWeight(1)
.backgroundColor(Color.White)
.width(500)
.height(40)
}@CustomDialog
struct CustomDialogWidget {
@State hobbyBeans: HobbyBean[] = [];@Prop title:string;
@Prop hobbyResult: Array<DataItemType>;
@Link hobbies: string;
private controller: CustomDialogController;setHobbiesValue(hobbyBeans: HobbyBean[]) {
let hobbiesText: string = '';
hobbiesText = hobbyBeans.filter((isCheckItem: HobbyBean) =>
isCheckItem?.isChecked)
.map((checkedItem: HobbyBean) => {
return checkedItem.label;
}).join(',');
this.hobbies = hobbiesText;
}aboutToAppear() {
// let context: Context = getContext(this);
// let manager = context.resourceManager;
// manager.getStringArrayValue($r('app.strarray.hobbies_data'), (error, hobbyResult) => {
// });
this.hobbyResult.forEach(item => {
const hobbyBean = {
label: item.value,
isChecked: this.hobbies.includes(item.value)
}
this.hobbyBeans.push(hobbyBean);
});
}
build() {
Column() {
Text(this.title || "兴趣爱好")
.fontWeight(FontWeight.Bold)
.alignSelf(ItemAlign.Start)
.margin({ left: 24, bottom: 12 })
List() {
ForEach(this.hobbyBeans, (itemHobby: HobbyBean) => {
ListItem() {
Row() {
Text(itemHobby.label)
.fontSize(16)
.fontColor("#182431")
.layoutWeight(1)
.textAlign(TextAlign.Start)
.fontWeight(500)
.margin({ left: 24 })
Toggle({ type: ToggleType.Checkbox, isOn: itemHobby.isChecked })
.margin({
right: 24
})
.onChange((isCheck) => {
itemHobby.isChecked = isCheck;
})
}
}
.height(36)
}, itemHobby => itemHobby.label)
}
.margin({
top: 6,
bottom: 8
})
.divider({
strokeWidth: 0.5,
color: "#0D182431"
})
.listDirection(Axis.Vertical)
.edgeEffect(EdgeEffect.None)
.width("100%")
// .height(248)Row({ space: 20 }) { Button("关闭") .dialogButtonStyle() .onClick(() => { this.controller.close(); }) Blank() .backgroundColor("#F2F2F2") .width(1) .opacity(1) .height(25) Button("保存") .dialogButtonStyle() .onClick(() => { this.setHobbiesValue(this.hobbyBeans); this.controller.close(); }) } } .width("93.3%") .padding({ top: 14, bottom: 16 }) .borderRadius(32) .backgroundColor(Color.White)
}
}@Entry
@Component
struct HomePage {
@State hobbies: string = '';
@State hobbyResult: Array<DataItemType> = [
{
"value": "FaceBook"
},
{
"value": "Google"
},
{
"value": "Instagram"
},
{
"value": "Twitter"
},
{
"value": "Linkedin"
}
]
private title: string = '常用网站'
customDialogController: CustomDialogController = new CustomDialogController({
builder: CustomDialogWidget({
hobbies: $hobbies,
hobbyResult: this.hobbyResult,
title: this.title
}),
alignment: DialogAlignment.Bottom,
customStyle: true,
offset: { dx: 0,dy: -20 }
});
build() {
Column() {
Button('打开自定义弹窗')
.width('60%')
.margin({top: 50})
.zIndex(999)
.onClick(()=>{
if (this.customDialogController != undefined) {
this.customDialogController.open()
}
})
Text(this.hobbies).fontSize(16).padding(24)
}
.width('100%')
}
}
写在最后
- 如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:
- 点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。
- 关注小编,同时可以期待后续文章ing🚀,不定期分享原创知识。