在我們?nèi)粘J褂脩?yīng)用的時(shí)候,可能會(huì)進(jìn)行一些敏感的操作,比如刪除聯(lián)系人,這時(shí)候我們給應(yīng)用添加彈窗來提示用戶是否需要執(zhí)行該操作,如下圖所示:
彈窗是一種模態(tài)窗口,通常用來展示用戶當(dāng)前需要的或用戶必須關(guān)注的信息或操作。在彈出框消失之前,用戶無法操作其他界面內(nèi)容。ArkUI為我們提供了豐富的彈窗功能,彈窗按照功能可以分為以下兩類:
- 確認(rèn)類:例如警告彈窗AlertDialog。
- 選擇類:包括文本選擇彈窗TextPickerDialog 、日期滑動(dòng)選擇彈窗DatePickerDialog、時(shí)間滑動(dòng)選擇彈窗TimePickerDialog等。
您可以根據(jù)業(yè)務(wù)場景,選擇不同類型的彈窗。部分彈窗效果圖如下:
此外,如果上述彈窗還不能滿足您的需求,或者需要對(duì)彈窗的布局和樣式進(jìn)行自定義,您還可以使用自定義彈窗CustomDialog。 下文將分別介紹AlertDialog 、TextPickerDialog 、DatePickerDialog以及CustomDialog的使用。
警告彈窗
警告彈窗AlertDialog由以下三部分區(qū)域構(gòu)成,對(duì)應(yīng)下面的示意圖:
- 標(biāo)題區(qū):為可選的。
- 內(nèi)容區(qū):顯示提示消息。
- 操作按鈕區(qū):用戶做”確認(rèn)“或者”取消“等操作。
以下示例代碼,演示了如何使用AlertDialog 實(shí)現(xiàn)上圖所示的警告彈窗。AlertDialog可以設(shè)置兩個(gè)操作按鈕,示例代碼中分別使用primaryButton和secondaryButton實(shí)現(xiàn)了“取消”和“刪除”操作按鈕,操作按鈕可以通過action響應(yīng)點(diǎn)擊事件。
Button('點(diǎn)擊顯示彈窗')
.onClick(() = > {
AlertDialog.show(
{
title: '刪除聯(lián)系人', // 標(biāo)題
message: '是否需要?jiǎng)h除所選聯(lián)系人?', // 內(nèi)容
autoCancel: false, // 點(diǎn)擊遮障層時(shí),是否關(guān)閉彈窗。
alignment: DialogAlignment.Bottom, // 彈窗在豎直方向的對(duì)齊方式
offset: { dx: 0, dy: -20 }, // 彈窗相對(duì)alignment位置的偏移量
primaryButton: {
value: '取消',
action: () = > {
console.info('Callback when the first button is clicked');
}
},
secondaryButton: {
value: '刪除',
fontColor: '#D94838',
action: () = > {
console.info('Callback when the second button is clicked');
}
},
cancel: () = > { // 點(diǎn)擊遮障層關(guān)閉dialog時(shí)的回調(diào)
console.info('Closed callbacks');
}
}
)
})
此外,您還可以使用AlertDialog,構(gòu)建只包含一個(gè)操作按鈕的確認(rèn)彈窗,使用confirm響應(yīng)操作按鈕回調(diào)。
AlertDialog.show(
{
title: '提示',
message: '提示信息',
autoCancel: true,
alignment: DialogAlignment.Bottom,
offset: { dx: 0, dy: -20 },
confirm: {
value: '確認(rèn)',
action: () = > {
console.info('Callback when confirm button is clicked');
}
},
cancel: () = > {
console.info('Closed callbacks')
}
}
)
選擇類彈窗
選擇類彈窗用于方便用戶選擇相關(guān)數(shù)據(jù),比如選擇喜歡吃的水果、出生日期等等。下面我們以TextPickerDialog和DatePickerDialog為例,來介紹選擇類彈窗的使用。
文本選擇彈窗
TextPickerDialog為文本滑動(dòng)選擇器彈窗,根據(jù)指定的選擇范圍創(chuàng)建文本選擇器,展示在彈窗上,例如下面這段示例代碼使用TextPickerDialog實(shí)現(xiàn)了一個(gè)水果選擇彈窗。示例代碼中使用selected指定了彈窗的初始選擇項(xiàng)索引為2,對(duì)應(yīng)的數(shù)據(jù)為“香蕉”。當(dāng)用戶點(diǎn)擊“確定”操作按鈕后,會(huì)觸發(fā)onAccept事件回調(diào),在回調(diào)中將選中的值,傳遞給宿主中的select變量。
@Entry
@Component
struct TextPickerDialogDemo {
@State select: number = 2;
private fruits: string[] = ['蘋果', '橘子', '香蕉', '獼猴桃', '西瓜'];
build() {
Column() {
Button('TextPickerDialog')
.margin(20)
.onClick(() = > {
TextPickerDialog.show({
range: this.fruits, // 設(shè)置文本選擇器的選擇范圍
selected: this.select, // 設(shè)置初始選中項(xiàng)的索引值。
onAccept: (value: TextPickerResult) = > { // 點(diǎn)擊彈窗中的“確定”按鈕時(shí)觸發(fā)該回調(diào)。
// 設(shè)置select為按下確定按鈕時(shí)候的選中項(xiàng)index,這樣當(dāng)彈窗再次彈出時(shí)顯示選中的是上一次確定的選項(xiàng)
this.select = value.index;
console.info("TextPickerDialog:onAccept()" + JSON.stringify(value));
},
onCancel: () = > { // 點(diǎn)擊彈窗中的“取消”按鈕時(shí)觸發(fā)該回調(diào)。
console.info("TextPickerDialog:onCancel()");
},
onChange: (value: TextPickerResult) = > { // 滑動(dòng)彈窗中的選擇器使當(dāng)前選中項(xiàng)改變時(shí)觸發(fā)該回調(diào)。
console.info('TextPickerDialog:onChange()' + JSON.stringify(value));
}
})
})
}
.width('100%')
}
}
效果圖如下:
日期選擇彈窗
下面我們介紹另一種常用的選擇類彈窗DatePickerDialog,它是日期滑動(dòng)選擇器彈窗,根據(jù)指定的日期范圍創(chuàng)建日期滑動(dòng)選擇器,展示在彈窗上。DatePickerDialog的使用非常廣泛,比如當(dāng)我們需要輸入個(gè)人出生日期的時(shí)候,就可以使用DatePickerDialog。下面的示例代碼實(shí)現(xiàn)了一個(gè)日期選擇彈窗:
@Entry
@Component
struct DatePickerDialogDemo {
selectedDate: Date = new Date('2010-1-1');
build() {
Column() {
Button("DatePickerDialog")
.margin(20)
.onClick(() = > {
DatePickerDialog.show({
start: new Date('1900-1-1'), // 設(shè)置選擇器的起始日期
end: new Date('2023-12-31'), // 設(shè)置選擇器的結(jié)束日期
selected: this.selectedDate, // 設(shè)置當(dāng)前選中的日期
lunar: false,
onAccept: (value: DatePickerResult) = > { // 點(diǎn)擊彈窗中的“確定”按鈕時(shí)觸發(fā)該回調(diào)
// 通過Date的setFullYear方法設(shè)置按下確定按鈕時(shí)的日期,這樣當(dāng)彈窗再次彈出時(shí)顯示選中的是上一次確定的日期
this.selectedDate.setFullYear(value.year, value.month, value.day)
console.info('DatePickerDialog:onAccept()' + JSON.stringify(value))
},
onCancel: () = > { // 點(diǎn)擊彈窗中的“取消”按鈕時(shí)觸發(fā)該回調(diào)
console.info('DatePickerDialog:onCancel()')
},
onChange: (value: DatePickerResult) = > { // 滑動(dòng)彈窗中的滑動(dòng)選擇器使當(dāng)前選中項(xiàng)改變時(shí)觸發(fā)該回調(diào)
console.info('DatePickerDialog:onChange()' + JSON.stringify(value))
}
})
})
}
.width('100%')
}
}
效果圖如下:
自定義彈窗
自定義彈窗的使用更加靈活,適用于更多的業(yè)務(wù)場景,在自定義彈窗中您可以自定義彈窗內(nèi)容,構(gòu)建更加豐富的彈窗界面。自定義彈窗的界面可以通過裝飾器@CustomDialog定義的組件來實(shí)現(xiàn),然后結(jié)合CustomDialogController來控制自定義彈窗的顯示和隱藏。下面我們通過一個(gè)興趣愛好的選擇框來介紹自定義彈窗的使用。
從上面的效果圖可以看出,這個(gè)選擇框是一個(gè)多選的列表彈窗,我們可以使用裝飾器@CustomDialog,結(jié)合List組件來完成這個(gè)彈窗布局,實(shí)現(xiàn)步驟如下:
- 初始化彈窗數(shù)據(jù)。先準(zhǔn)備好資源文件和數(shù)據(jù)實(shí)體類。其中資源文件stringarray.json創(chuàng)建在resources/base/element目錄下,文件根節(jié)點(diǎn)為strarray。
{
"strarray": [
{
"name": "hobbies_data",
"value": [
{
"value": "Soccer"
},
{
"value": "Badminton"
},
{
"value": "Travelling"
},
...
]
}
]
}
實(shí)體類HobbyBean用來封裝自定義彈窗中的"興趣愛好"數(shù)據(jù)。
export default class HobbyBean {
label: string;
isChecked: boolean;
}
然后創(chuàng)建一個(gè)ArkTS文件CustomDialogWidget,用來封裝自定義彈窗,使用裝飾器@CustomDialog修飾CustomDialogWidget表示這是一個(gè)自定義彈窗。使用資源管理對(duì)象manager獲取數(shù)據(jù),并將數(shù)據(jù)封裝到hobbyBeans。
@CustomDialog
export default struct CustomDialogWidget {
@State hobbyBeans: HobbyBean[] = [];
aboutToAppear() {
let context: Context = getContext(this);
let manager = context.resourceManager;
manager.getStringArrayValue($r('app.strarray.hobbies_data'), (error, hobbyResult) = > {
...
hobbyResult.forEach((hobbyItem: string) = > {
let hobbyBean = new HobbyBean();
hobbyBean.label = hobbyItem;
hobbyBean.isChecked = false;
this.hobbyBeans.push(hobbyBean);
});
});
}
build() {...}
}
- 創(chuàng)建彈窗組件。controller對(duì)象用于控制彈窗的控制和隱藏,hobbies表示彈窗選中的數(shù)據(jù)結(jié)果。setHobbiesValue方法用于篩選出被選中的數(shù)據(jù),賦值給hobbies。
@CustomDialog
export default struct CustomDialogWidget {
@State hobbyBeans: HobbyBean[] = [];
@Link hobbies: string;
private controller?: CustomDialogController;
aboutToAppear() {...}
setHobbiesValue(hobbyBeans: HobbyBean[]) {
let hobbiesText: string = '';
hobbiesText = hobbyBeans.filter((isCheckItem: HobbyBean) = >
isCheckItem?.isChecked)
.map((checkedItem: HobbyBean) = > {
return checkedItem.label;
}).join(',');
this.hobbies = hobbiesText;
}
build() {
Column() {
Text($r('app.string.text_title_hobbies'))...
List() {
ForEach(this.hobbyBeans, (itemHobby: HobbyBean) = > {
ListItem() {
Row() {
Text(itemHobby.label)...
Toggle({ type: ToggleType.Checkbox, isOn: false })...
.onChange((isCheck) = > {
itemHobby.isChecked = isCheck;
})
}
}
}, itemHobby = > itemHobby.label)
}
Row() {
Button($r('app.string.cancel_button'))...
.onClick(() = > {
this.controller?.close();
})
Button($r('app.string.definite_button'))...
.onClick(() = > {
this.setHobbiesValue(this.hobbyBeans);
this.controller?.close();
})
}
}
}
}
- 使用自定義彈窗。在自定義彈窗的使用頁面HomePage中先定義一個(gè)變量hobbies,使用裝飾器@State修飾,和自定義彈窗中的@Link 裝飾器修飾的變量進(jìn)行雙向綁定。然后我們使用alignment和offset設(shè)置彈窗的位置在屏幕底部,并且距離底部20vp。最后我們在自定義組件TextCommonWidget(具體實(shí)現(xiàn)可以參考《構(gòu)建多種樣式彈窗》Codelab源碼)的點(diǎn)擊事件中,調(diào)用customDialogController的open方法,用于顯示彈窗。
@Entry
@Component
struct HomePage {
customDialogController: CustomDialogController = new CustomDialogController({
builder: CustomDialogWidget({
onConfirm: this.setHobbiesValue.bind(this),
}),
alignment: DialogAlignment.Bottom,
customStyle: true,
offset: { dx: 0,dy: -20 }
});
setHobbiesValue(hobbyArray: HobbyBean[]) {...}
build() {
...
TextCommonWidget({
...
title: $r('app.string.title_hobbies'),
content: $hobby,
onItemClick: () = > {
this.customDialogController.open();
}
})
...
}
}
審核編輯 黃宇
-
鴻蒙
+關(guān)注
關(guān)注
57文章
2302瀏覽量
42689 -
OpenHarmony
+關(guān)注
關(guān)注
25文章
3635瀏覽量
16061
發(fā)布評(píng)論請先 登錄
相關(guān)推薦
評(píng)論