一、簡介
開發者對彈出框的定製不僅限於彈出框裏的內容,對彈出框蒙層的定製需求也逐漸增加。本文介紹ArkUI彈出框的蒙層控制,包括點擊蒙層時是否消失、蒙層區域、蒙層顏色和蒙層動畫等特性。
二、使用約束
ArkUI提供多種彈出框,不同類型的彈出框具備不同的蒙層定製能力。詳情請參閲下表:
|
接口&組件
|
autoCancel
|
maskRect
|
isModal
|
immersiveMode
|
|
openCustomDialog
|
支持
|
支持
|
支持
|
支持
|
|
openCustomDialogWithController
|
支持
|
支持
|
支持
|
支持
|
|
presentCustomDialog
|
支持
|
支持
|
支持
|
支持
|
|
updateCustomDialog
|
支持
|
不支持
|
不支持
|
不支持
|
|
CustomDialog
|
支持
|
支持
|
支持
|
支持
|
|
showDialog
|
不支持
|
支持
|
支持
|
支持
|
|
showAlertDialog
|
支持
|
支持
|
支持
|
支持
|
|
showActionSheet
|
支持
|
支持 支持
|
支持
|
|
|
showActionMenu
|
不支持
|
不支持
|
支持
|
支持
|
|
showDatePickerDialog
|
不支持
|
支持
|
不支持
|
不支持
|
|
CalendarPickerDialog
|
不支持
|
不支持
|
不支持
|
不支持
|
|
showTimePickerDialog
|
不支持
|
支持
|
不支持
|
不支持
|
|
showTextPickerDialog
|
不支持
|
支持
|
不支持
|
不支持
|
説明 設置autoCancel參數,可控制彈出框蒙層被點擊時是否消失。
設置maskRect參數,可定製彈出框的蒙層的大小和位置進行定製。此外,蒙層範圍內的事件無法透傳,而蒙層範圍外的事件可以透傳。
設置isModal參數,可定製彈出框的模態狀態:非模態彈出框無蒙層,支持與周圍組件交互;模態彈出框有蒙層,禁止與周圍組件交互。
當levelMode屬性設置為LevelMode.EMBEDDED時,設置immersiveMode參數,可定製彈出框蒙層是否延伸至狀態欄及導航欄。
|
接口&組件
|
maskColor
|
transition
|
maskTransition
|
|
openCustomDialog
|
支持
|
支持
|
支持
|
|
openCustomDialogWithController
|
支持
|
支持
|
支持
|
|
presentCustomDialog 支持
|
支持
|
支持
|
|
|
updateCustomDialog
|
支持
|
不支持
|
不支持
|
|
CustomDialog
|
支持
|
不支持(可由openAnimation和closeAnimation替代)
|
不支持
|
|
showDialog
|
不支持
|
不支持
|
不支持
|
|
showAlertDialog
|
不支持
|
支持
|
不支持
|
|
showActionSheet
|
不支持
|
支持
|
不支持
|
|
showActionMenu
|
不支持
|
不支持
|
不支持
|
|
showDatePickerDialog
|
不支持
|
不支持
|
不支持
|
|
CalendarPickerDialog
|
不支持
|
不支持
|
不支持
|
|
showTimePickerDialog
|
不支持
|
不支持
|
不支持
|
|
showTextPickerDialog
|
不支持
|
不支持
|
不支持
|
説明 設置maskColor參數,可定製彈出框蒙層的顏色。
設置openAnimation參數,可定製彈出框的進入動畫,同時影響蒙層動畫。該接口僅支持簡單的動畫設置,不支持複雜動畫定製。
設置closeAnimation參數,可定製彈出框的退出動畫,同時影響蒙層動畫。該接口僅支持簡單的動畫設置,不支持複雜動畫定製。
設置transition參數,可定製彈出框的進入和退出動畫,同時影響蒙層動畫。
設置maskTransition參數,可定製彈出框的蒙層動畫。
三、彈出框蒙層顯隱控制
通過autoCancel,isModal展示彈出框在蒙層顯隱控制方面的能力。
設置autoCancel為false,取消默認點擊蒙層時彈窗消失。
// xxx.ets
autoCancelOpt: promptAction.CustomDialogOptions = {
builder: () => {
this.myBuilder();
},
autoCancel: false,
} as promptAction.CustomDialogOptions;
Button("openCustomDialog autoCancel:false")
.width('100%')
.margin({ top: 10 })
.onClick(() => {
this.getUIContext().getPromptAction().openCustomDialog(this.autoCancelOpt)
})
設置isModal為false,將默認的模態彈出框變為非模態彈出框。
// xxx.ets
modalOpt: promptAction.CustomDialogOptions = {
builder: () => {
this.myBuilder();
},
isModal: false,
} as promptAction.CustomDialogOptions;
Button("openCustomDialog isModal:false")
.width('100%')
.margin({ top: 10 })
.onClick(() => {
this.getUIContext().getPromptAction().openCustomDialog(this.modalOpt)
})
四、彈出框蒙層樣式控制
該示例通過maskRect、immersiveMode和maskColor展示彈出框在蒙層樣式控制方面的能力。
設置maskRect和maskColor,實現蒙層區域和蒙層顏色的設置。
// xxx.ets
maskOpt: promptAction.CustomDialogOptions = {
builder: () => {
this.myBuilder();
},
maskRect: {
x: 0,
y: 10,
width: '100%',
height: '90%'
},
maskColor: "#33AA0000"
} as promptAction.CustomDialogOptions;
Button("openCustomDialog maskOpt")
.width('100%')
.margin({ top: 10 })
.onClick(() => {
this.getUIContext().getPromptAction().openCustomDialog(this.maskOpt)
})
在levelMode為LevelMode.EMBEDDED下,展示不同immersiveMode對蒙層在導航欄和狀態欄的延伸效果。
// xxx.ets
@State immersiveMode: ImmersiveMode = ImmersiveMode.DEFAULT;
Button("openCustomDialog immersiveMode")
.width('100%')
.margin({ top: 10 })
.onClick(() => {
this.immersiveMode =
this.immersiveMode == ImmersiveMode.DEFAULT ? ImmersiveMode.EXTEND : ImmersiveMode.DEFAULT;
this.getUIContext().getPromptAction().openCustomDialog({
builder: () => {
this.myBuilder();
},
levelMode: LevelMode.EMBEDDED,
immersiveMode: this.immersiveMode,
})
})
五、彈出框蒙層動畫控制
該示例通過transition和maskTransition分別展示彈出框在蒙層動畫方面的能力。
設置transition,實現彈出框與蒙層整體的動畫。
// xxx.ets
transitionOpt: promptAction.CustomDialogOptions = {
builder: () => {
this.myBuilder();
},
transition: TransitionEffect.OPACITY.animation({ duration: 3000 })
} as promptAction.CustomDialogOptions;
Button("openCustomDialog transition")
.width('100%')
.margin({ top: 10 })
.onClick(() => {
this.getUIContext().getPromptAction().openCustomDialog(this.transitionOpt);
})
設置maskTransition,實現彈出框中蒙層單獨的動畫定製能力。
// xxx.ets
Button("openCustomDialog maskTransition")
.width('100%')
.margin({ top: 10 })
.onClick(() => {
this.getUIContext().getPromptAction().openCustomDialog({
builder: () => {
this.myBuilder();
},
maskTransition: TransitionEffect.OPACITY.animation({ duration: 2000 })
.combine(TransitionEffect.rotate({ z: 1, angle: 180 })),
});
})
CustomDialog雖然不支持transition接口,但與之對應的openAnimation和closeAnimation接口在動畫的打開和關閉時可進行定製,示例代碼如下:
// xxx.ets
@CustomDialog
@Component
struct CustomDialogExample {
controller?: CustomDialogController;
build() {
Column() {
Text("title")
.margin(10)
.fontSize(20)
Button("button1")
.margin(10)
.fontSize(20)
.onClick(() => {
this.controller?.close();
})
Button("button2")
.margin(10)
.fontSize(20)
.onClick(() => {
this.controller?.close();
})
}.width('100%')
.height('50%')
}
}
@Entry
@Component
struct Index {
animationController: CustomDialogController | null
= new CustomDialogController({
builder: CustomDialogExample(),
closeAnimation: { duration: 2000 },
openAnimation: { duration: 2000 }
});
aboutToDisappear(): void {
this.animationController = null;
}
build() {
Column() {
Button("CustomDialogController animate")
.width('100%')
.margin({ top: 10 })
.onClick(() => {
this.animationController?.open();
})
}
}
}
六、完整示例
效果圖
示例代碼
import { ImmersiveMode, LevelMode, promptAction } from '@kit.ArkUI';
@Entry
@Component
struct TestOpenCustomDialog7 {
@State immersiveMode: ImmersiveMode = ImmersiveMode.DEFAULT;
autoCancelOpt: promptAction.CustomDialogOptions = {
builder: () => {
this.myBuilder();
},
autoCancel: false,
} as promptAction.CustomDialogOptions;
modalOpt: promptAction.CustomDialogOptions = {
builder: () => {
this.myBuilder();
},
isModal: false,
} as promptAction.CustomDialogOptions;
maskOpt: promptAction.CustomDialogOptions = {
builder: () => {
this.myBuilder();
},
maskRect: {
x: 0,
y: 10,
width: '100%',
height: '90%'
},
maskColor: "#33AA0000"
} as promptAction.CustomDialogOptions;
transitionOpt: promptAction.CustomDialogOptions = {
builder: () => {
this.myBuilder();
},
transition: TransitionEffect.OPACITY.animation({ duration: 3000 })
} as promptAction.CustomDialogOptions;
@Builder
myBuilder() {
Column() {
Text("title").margin(10).fontSize(20)
Button("button1").margin(10).fontSize(20)
Button("button2").margin(10).fontSize(20)
}.width('100%').height('50%')
}
build() {
Column({space: 10}) {
Button("openCustomDialog autoCancel:false")
.width('100%')
.margin({ top: 10 })
.onClick(() => {
this.getUIContext().getPromptAction().openCustomDialog(this.autoCancelOpt)
})
Button("openCustomDialog isModal:false")
.width('100%')
.margin({ top: 10 })
.onClick(() => {
this.getUIContext().getPromptAction().openCustomDialog(this.modalOpt)
})
Button("openCustomDialog maskOpt")
.width('100%')
.margin({ top: 10 })
.onClick(() => {
this.getUIContext().getPromptAction().openCustomDialog(this.maskOpt)
})
Button("openCustomDialog transition")
.width('100%')
.margin({ top: 10 })
.onClick(() => {
this.getUIContext().getPromptAction().openCustomDialog(this.transitionOpt);
})
Button("openCustomDialog immersiveMode")
.width('100%')
.margin({ top: 10 })
.onClick(() => {
this.immersiveMode =
this.immersiveMode == ImmersiveMode.DEFAULT ? ImmersiveMode.EXTEND : ImmersiveMode.DEFAULT;
this.getUIContext().getPromptAction().openCustomDialog({
builder: () => {
this.myBuilder();
},
levelMode: LevelMode.EMBEDDED,
immersiveMode: this.immersiveMode,
})
})
Button("openCustomDialog maskTransition")
.width('100%')
.margin({ top: 10 })
.onClick(() => {
this.getUIContext().getPromptAction().openCustomDialog({
builder: () => {
this.myBuilder();
},
maskTransition: TransitionEffect.OPACITY.animation({ duration: 2000 })
.combine(TransitionEffect.rotate({ z: 1, angle: 180 })),
});
})
}
.width('100%')
.height('100%')
}
}