前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >鸿蒙开发实战案例:编辑收货地址案例

鸿蒙开发实战案例:编辑收货地址案例

原创
作者头像
小帅聊鸿蒙
发布2025-02-25 13:46:12
发布2025-02-25 13:46:12
770
举报
文章被收录于专栏:鸿蒙开发笔记鸿蒙开发笔记

介绍

本示例多用于表单填写场景:其中通过使用TextPicker滑动选择文本内容组件实现三级联动选择省市区,并回填到输入框。

效果图预览

使用说明

  1. 点击编辑收货地址案例。
  2. 点击所在地区的输入框,弹出TextPicker组件,滑动选择省市区等待滑动结束静止后,点击确认,省市区回填到输入框中。
  3. 点击底部的保存按钮时,表单会从上到下逐个验证,例如当用户同时未输入收件人和手机号时,会优先弹窗提示"姓名不能为空", 当收件人填写完成,手机号没填时,点击保存,会弹窗提示"手机号不能为空",以此类推直到收件人、手机号、所在地区、详细地址输入框都填写完成,点击按钮弹窗 "保存成功,此样式仅为案例展示"。

实现思路

场景:通过使用TextPicker滑动选择文本内容组件实现三级联动选择省市区,并回填到输入框。

  1. 通过给TextInput组件绑定半模态转场,与TextPicker组件结合,实现点击所在地区的输入框时,弹出半模态页面里选择省市区的样式。
代码语言:typescript
复制
@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数据。
代码语言:typescript
复制
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}.`);
}
}
DD一下:欢迎大家关注公众号<程序猿百晓生>,可以了解到一下知识点。
代码语言:erlang
复制
1.OpenHarmony开发基础
2.OpenHarmony北向开发环境搭建
3.鸿蒙南向开发环境的搭建
4.鸿蒙生态应用开发白皮书V2.0 & V3.0
5.鸿蒙开发面试真题(含参考答案) 
6.TypeScript入门学习手册
7.OpenHarmony 经典面试题(含参考答案)
8.OpenHarmony设备开发入门【最新版】
9.沉浸式剖析OpenHarmony源代码
10.系统定制指南
11.【OpenHarmony】Uboot 驱动加载流程
12.OpenHarmony构建系统--GN与子系统、部件、模块详解
13.ohos开机init启动流程
14.鸿蒙版性能优化指南
.......
  1. 当滑动选中TextPicker文本内容后,通过.onChange((value: string | string[])触发回调,通过返回的当前选中项的索引值Index选中项数组对象进行循环处理,得到处理好的省市区字符串,点击"确认"时赋值给TextInput,完成回填。
代码语言:typescript
复制
/**
 * 从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条件验证从而实现表单从上到下必填验证功能。
代码语言:typescript
复制
/**
 * 保存时,校验表单从上到下每项必填的方法
 */
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🚀,不定期分享原创知识;
  • 想要获取更多完整鸿蒙最新学习知识点,可关注B站:码牛课堂;

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 介绍
    • 效果图预览
    • 实现思路
      • DD一下:欢迎大家关注公众号<程序猿百晓生>,可以了解到一下知识点。
  • 写在最后
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档