鴻蒙開發實戰案例:編輯收貨地址案例

介紹

本示例多用于表單填寫場景:其中通過使用TextPicker滑動選擇文本內容組件實現三級聯動選擇省市區,并回填到輸入框。

效果圖預覽

使用說明

  1. 點擊編輯收貨地址案例。
  2. 點擊所在地區的輸入框,彈出TextPicker組件,滑動選擇省市區等待滑動結束靜止后,點擊確認,省市區回填到輸入框中。
  3. 點擊底部的保存按鈕時,表單會從上到下逐個驗證,例如當用戶同時未輸入收件人和手機號時,會優先彈窗提示"姓名不能為空",
    當收件人填寫完成,手機號沒填時,點擊保存,會彈窗提示"手機號不能為空",以此類推直到收件人、手機號、所在地區、詳細地址輸入框都填寫完成,點擊按鈕彈窗
    "保存成功,此樣式僅為案例展示"。

實現思路

場景:通過使用TextPicker滑動選擇文本內容組件實現三級聯動選擇省市區,并回填到輸入框。

  1. 通過給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();
      })
    })
}
  1. 定義省市區的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}.`);
}
}
  1. 當滑動選中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 })
}
  1. 通過點擊保存按鈕時,觸發嵌套的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
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,837評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,196評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,688評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,654評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,456評論 6 406
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,955評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,044評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,195評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,725評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,608評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,802評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,318評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,048評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,422評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,673評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,424評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,762評論 2 372

推薦閱讀更多精彩內容