介紹
本示例多用于表單填寫場景:其中通過使用TextPicker滑動選擇文本內容組件實現三級聯動選擇省市區,并回填到輸入框。
效果圖預覽
使用說明
- 點擊編輯收貨地址案例。
- 點擊所在地區的輸入框,彈出TextPicker組件,滑動選擇省市區等待滑動結束靜止后,點擊確認,省市區回填到輸入框中。
- 點擊底部的保存按鈕時,表單會從上到下逐個驗證,例如當用戶同時未輸入收件人和手機號時,會優先彈窗提示"姓名不能為空",
當收件人填寫完成,手機號沒填時,點擊保存,會彈窗提示"手機號不能為空",以此類推直到收件人、手機號、所在地區、詳細地址輸入框都填寫完成,點擊按鈕彈窗
"保存成功,此樣式僅為案例展示"。
實現思路
場景:通過使用TextPicker滑動選擇文本內容組件實現三級聯動選擇省市區,并回填到輸入框。
- 通過給TextInput組件綁定半模態轉場,與TextPicker組件結合,實現點擊所在地區的輸入框時,彈出半模態頁面里選擇省市區的樣式。
@Builder
halfModalLogin() { // 半模態窗口頁面
Column() {
Row({ space: SPACE_THIRTY }) {
Text($r('app.string.editaddress_bind_sheet_cancel'))
.fontColor("#256fb5")
.fontSize(18)
.fontWeight(450)
.padding({ bottom: 15, left: 50 })
.onClick(() => {
this.isPresent = !this.isPresent;
})
Text($r('app.string.editaddress_bind_sheet_title'))
.fontColor(Color.Black)
.fontSize(19)
.padding({ bottom: 15 })
Text($r('app.string.editaddress_bind_sheet_verify'))
.fontColor("#256fb5")
.fontSize(18)
.fontWeight(450)
.padding({ bottom: 15 })
.onClick(() => {
// ...
})
}
.padding({ top: 20 })
.backgroundColor($r('app.color.editaddress_bind_sheet_title_bgc'))
.width('100%')
TextPicker({ range: cascade, selected: this.addressForm.provinceArr })
// TODO:滑動選中TextPicker文本內容后,觸發該回調。當顯示文本或圖片加文本列表時,value值為選中項中的文本值
.onChange((value: string | string[], index: number | number[]) => {
if (index instanceof Array) {
this.addressForm.provinceArr = index;
}
})
.padding({ top: 15 })
}
}
build() {
// ...
TextInput({ placeholder: '省、市、區', text: this.addressForm.province })
/**
* TODO: 知識點: 通過bindSheet屬性為組件綁定半模態頁面,由于半模態必須綁定組件,
* 此處綁定TextInput組件配合TextPicker作為半模態展示。
* isPresent:是否顯示半模態頁面
*/
.bindSheet($$this.isPresent, this.halfModalLogin(), {
// TextInput綁定半模態轉場
height: this.sheetHeight, // 半模態高度
dragBar: this.showDragBar, // 是否顯示控制條
// 平板或折疊屏展開態在中間顯示
preferType: this.isCenter ? SheetType.CENTER : SheetType.POPUP,
backgroundColor: $r('app.color.editaddress_btn_bgc'),
showClose: false, // 是否顯示關閉圖標
shouldDismiss: ((sheetDismiss: SheetDismiss) => { // 半模態頁面交互式關閉回調函數
sheetDismiss.dismiss();
})
})
}
- 定義省市區的json格式數據存放在文件中,通過在aboutToAppear()中調用loadRegion(),從文件中讀取省市區json數據。
aboutToAppear(): void {
this.loadRegion();
}
/**
* 從文件中讀取省市區json數據
*/
async loadRegion(): Promise<void> {
try {
// 通過getRawFileContent()獲取resources/rawfile目錄下對應的文件內容,得到一個字節數組
getContext(this).resourceManager.getRawFileContent(this.fileName, (error: BusinessError, value: Uint8Array) => {
let rawFile = value;
let textDecoder = util.TextDecoder.create('utf-8', { ignoreBOM: true });
let retStr = textDecoder.decodeToString(rawFile, { stream: false }); // 再用@ohos.util (util工具函數)的TextDecoder給它解析出來
this.cascade = JSON.parse(retStr);
})
} catch (error) {
let code = (error as BusinessError).code;
let message = (error as BusinessError).message;
console.error(`callback getRawFileContent failed, error code: ${code}, message: ${message}.`);
}
}
- 當滑動選中TextPicker文本內容后,通過.onChange((value: string | string[])觸發回調,通過返回的當前選中項的索引值Index選中項數組對象進行循環處理,得到處理好的省市區字符串,點擊"確認"時賦值給TextInput,完成回填。
/**
* 從TextPicker返回選中的數據中逐級查找省、市、區的名稱,并將其組合成一個完整的地址字符串。
*/
getSelectedPlace() {
if (this.addressForm.provinceArr instanceof Array) {
let province = this.cascade[this.addressForm.provinceArr[0]]; // 獲取省信息
let areaName = ""; // 存儲最終構建的省市區名稱
if (province) {
areaName += this.cascade[this.addressForm.provinceArr[0]].text; // 省的名稱添加到容器里
if (province.children) { // 檢查是否有市的信息
let city = province.children[this.addressForm.provinceArr[1]]; // 市的名稱添加到容器里
if (city) {
areaName += city.text;
if (city.children) { // 檢查是否有區的信息
areaName += city.children[this.addressForm.provinceArr[2]].text; // 區的名稱添加到容器里
}
}
}
}
this.addressForm.areaName = areaName; // 將取出的省市區拼接的字符串回填給TextInput
return;
}
}
@Builder
halfModalLogin() { // 半模態窗口頁面
Column() {
Row({ space: SPACE_THIRTY }) {
// 半模態的確認按鈕
Text($r('app.string.editaddress_bind_sheet_verify'))
.onClick(() => {
this.getSelectedPlace();
})
}
TextPicker({ range: cascade, selected: this.addressForm.provinceArr })
// TODO:滑動選中TextPicker文本內容后,觸發該回調。當顯示文本或圖片加文本列表時,value值為選中項中的文本值
.onChange((value: string | string[], index: number | number[]) => {
if (index instanceof Array) {
this.addressForm.provinceArr = index;
}
})
// 設置所有選項中除了最上、最下及選中項以外的文本顏色、字號、字體粗細。
.textStyle({
color: $r('app.color.editaddress_textStyle_font_color'),
font: {
size: $r('app.string.editaddress_textStyle_font_size'),
weight: FontWeight.Regular
}
})
// 設置選中項的文本顏色、字號、字體粗細。
.selectedTextStyle({
color: $r('app.color.editaddress_selectedTextStyle_font_color'),
font: {
size: $r('app.string.editaddress_selectedTextStyle_font_size'),
weight: FontWeight.Medium
}
})
}
}
build() {
// ...
// 通過text屬性
TextInput({ placeholder: '省、市、區', text: this.addressForm.province })
}
- 通過點擊保存按鈕時,觸發嵌套的if條件驗證從而實現表單從上到下必填驗證功能。
/**
* 保存時,校驗表單從上到下每項必填的方法
*/
validForm(): boolean {
if (!this.addressForm.name) {
promptAction.showToast({ message: $r('app.string.editaddress_name_judge') });
return false;
}
if (!this.addressForm.phone) {
promptAction.showToast({ message: $r('app.string.editaddress_phone_judge') });
return false;
}
if (this.addressForm.phone.length < 11) {
promptAction.showToast({ message: $r('app.string.editaddress_phone_judge_less_eleven') });
return false;
}
if (!this.addressForm.areaName) {
promptAction.showToast({ message: $r('app.string.editaddress_place_judge') });
return false;
}
if (!this.addressForm.area) {
promptAction.showToast({ message: $r('app.string.editaddress_detail_address_judge') });
return false;
}
return true;
}
build() {
// ...
Text('保存')
.onClick(() => {
if (this.validForm()) {
promptAction.showToast({ message: $r('app.string.editaddress_save_success') });
}
})
}
寫在最后
- 如果你覺得這篇內容對你還蠻有幫助,我想邀請你幫我三個小忙:
- 點贊,轉發,有你們的 『點贊和評論』,才是我創造的動力。
- 關注小編,同時可以期待后續文章ing??,不定期分享原創知識。
- 想要獲取更多完整鴻蒙最新學習知識點,請移步前往小編:
https://gitee.com/MNxiaona/733GH/blob/master/jianshu