功能点:支持三级联动、点击确认返回省市区code及name(安心)、布局可以高度自定义

实现:TextPicker+读取本地json(也可用第三方的json 不过需要自行调整了)
先上图吧、废话下面再说:

凑和看吧、(可能是虚拟机卡、或者动画原因、联动会慢一些)

调用:
 

  方式一 1、//注意调用处是在ets @Component 组件中let areaData = await AreaDataUtil.loadJsonFile(getContext())GlobalAreaPicker.show(this.getUIContext(),{areaData: areaData,onConfirm: (province, city, county,addr) => {//或者直接用addrconsole.log(`选中:${province.name} ${city.name} ${county.name}`);},onCancel: () => {console.log('取消选择');}})方式二 2、//调用注意调用处是在ets @Component 组件中showAreaPicker(this.getUIContext(), (province, city, county,addr) => {// this.companyAddress = `${province.name} ${city.name} ${county.name}`;})

1、主要类说明看截图

补充代码截图

2、上代码 :
2.1 GlobalAreaPicker.ets(核心实现类)

// GlobalAreaPicker.ets
import { JsonAddr } from '../utils/AreaDataUtil';
import { ComponentContent } from '@kit.ArkUI';
import { FontDiy, TextStyleModifier } from './style/TextStyles';
import { IS_PREVIEW } from 'models';
import { DIVIDER_COLOR } from '../constant/ColorConstant';//地址选择器参数传递
export interface AreaSelectOption {areaData: JsonAddr[],onConfirm?: (province: JsonAddr, city: JsonAddr, county: JsonAddr,addressInfo:string) => void,//addressInfo 拼接好的地址 默认空格隔开onCancel?: () => void// 反正我没用着、留着呗
}//全局弹窗封装、不依赖沙雕Pager
export class GlobalAreaPicker {static contentNode?: ComponentContent<Object>static show(uiContext: UIContext, options: AreaSelectOption) {GlobalAreaPicker.contentNode = new ComponentContent(uiContext,wrapBuilder(buildAreaPicker),options);uiContext.getPromptAction().openCustomDialog(GlobalAreaPicker.contentNode, {alignment: DialogAlignment.Bottom,autoCancel: true,});}static close(uiContext: UIContext) {if (GlobalAreaPicker.contentNode !== null) {uiContext.getPromptAction().closeCustomDialog(GlobalAreaPicker.contentNode)}}
}//全局弹窗需要、甲鱼的屁股-》规定
@Builder
function buildAreaPicker(params: AreaSelectOption) {AreaPickerContent({areaData: params.areaData,onConfirm: params.onConfirm,onCancel: params.onCancel})
}// 弹窗内容组件(开业)
// @Preview 需要虚拟机运行才行、
@Component
struct AreaPickerContent {@Prop areaData: JsonAddr[] = [];@State selectedProvince: JsonAddr | null = null;@State selectedCity: JsonAddr | null = null;@State selectedCounty: JsonAddr | null = null;@State provinceIndex: number = 0;@State cityIndex: number = 0;@State countyIndex: number = 0;// TextPicker 数据@State provinceNames: string[] = [];@State cityNames: string[] = [];@State countyNames: string[] = [];onConfirm?: (province: JsonAddr, city: JsonAddr, county: JsonAddr,addressInfo:string) => void;onCancel?: () => void;aboutToAppear() {this.provinceNames = this.areaData.map(p => p.name);this.initDefaultSelection();}initDefaultSelection() {if (this.areaData.length > 0) {this.selectedProvince = this.areaData[0];this.provinceIndex = 0;this.updateCities();}}updateCities() {if (this.selectedProvince?.children && this.selectedProvince.children.length > 0) {this.cityNames = this.selectedProvince.children.map(c => c.name);this.selectedCity = this.selectedProvince.children[0];this.cityIndex = 0;this.updateCounties();}}updateCounties() {if (this.selectedCity?.children && this.selectedCity.children.length > 0) {this.countyNames = this.selectedCity.children.map(c => c.name);this.selectedCounty = this.selectedCity.children[0];this.countyIndex = 0;}}build() {Column() {// 顶部操作栏Row() {Text('取消').attributeModifier(new TextStyleModifier(16, '#999999', FontDiy.MEDIUM, IS_PREVIEW)).onClick(() => {GlobalAreaPicker.close(this.getUIContext());this.onCancel?.();})Blank()Text('确认').attributeModifier(new TextStyleModifier(16, '#1778FF', FontDiy.MEDIUM, IS_PREVIEW)).onClick(() => {if (this.selectedProvince && this.selectedCity && this.selectedCounty) {this.onConfirm?.(this.selectedProvince,this.selectedCity,this.selectedCounty,`${this.selectedProvince.name}${this.selectedCity.name.includes('市辖区')?' ':` ${this.selectedCity.name} `}${this.selectedCounty.name}`//拼接字符串地址(过滤掉市辖区));}GlobalAreaPicker.close(this.getUIContext());})}.width('100%').height(44).padding({ left: 16, right: 16 })Divider().color('#f0f0f0')Row() {// 省份TextPicker({ range: this.provinceNames, selected: this.provinceIndex }).width('33.33%').height(250).canLoop(false).selectTextStyle()//往下扒拉扒拉 能找到.onChange((value: string | string[], index: number | number[]) => {if (typeof index === 'number') {this.provinceIndex = index;this.selectedProvince = this.areaData[index];this.updateCities();}})// 城市TextPicker({ range: this.cityNames, selected: this.cityIndex }).width('33.33%').height(250).canLoop(false).selectTextStyle().onChange((value: string | string[], index: number | number[]) => {if (typeof index === 'number' && this.selectedProvince?.children) {this.cityIndex = index;this.selectedCity = this.selectedProvince.children[index];this.updateCounties();}})// 区县TextPicker({ range: this.countyNames, selected: this.countyIndex }).width('33.33%').height(250).canLoop(false).selectTextStyle().onChange((value: string | string[], index: number | number[]) => {if (typeof index === 'number' && this.selectedCity?.children) {this.countyIndex = index;this.selectedCounty = this.selectedCity.children[index];}})}}.backgroundColor(Color.White).borderRadius({ topLeft: 12, topRight: 12 })}
}
//扩展属性
@Extend(TextPicker)
function selectTextStyle() {.selectedTextStyle({color: '#333333', font: {size: 18, family:$r('[base].media.pf_medium')}})//报错 删了family就行、自定义字体.textStyle({color: '#999999', font: {size: 16, family:$r('[base].media.pf_regular')}}).disappearTextStyle({color: '#999999', font: {size: 14, family:$r('[base].media.pf_regular')}}).divider({color: DIVIDER_COLOR,//#d5d5d5} as DividerOptions)
}/*
// 使用方式
GlobalAreaPicker.show({areaData: yourAreaData,onConfirm: (province, city, county) => {console.log(`选中:${province.name} ${city.name} ${county.name}`);},onCancel: () => {console.log('取消选择');}
});*/

2.2 AreaDataUtil.ts(读取地址json)

import { logger } from "../../../mock/baseMock";
import { Context } from "@kit.AbilityKit";
import { util } from "@kit.ArkTS";// utils/AreaDataUtil.ets
export class AreaDataUtil {private static JsonAddr: JsonAddr[] = []//读取本地json文件static async loadJsonFile(context: Context): Promise<JsonAddr[]> {if (this.JsonAddr.length > 0) {logger.info('loadJsonFile stop read reason: has address '+AreaDataUtil.JsonAddr.length)return AreaDataUtil.JsonAddr}try {logger.info('开始读取地址 ')const mgr = context.resourceManager;const value = await mgr.getRawFileContent('newprovince.json');const textDecoder = util.TextDecoder.create('utf-8');const jsonStr = textDecoder.decodeWithStream(value);logger.info('地址读取完成 ')let ja = JSON.parse(jsonStr) as JsonAddr[]AreaDataUtil.JsonAddr = jareturn ja;} catch (error) {console.error('读取JSON失败', error);return null;}}
}//地址选择
/*export interface AreaList {province_list: Record<string, string>city_list: Record<string, string>county_list: Record<string, string>test: CascaderOption[]
}*///映射第三库的地址
export interface CascaderOption {text: stringvalue: stringchildren?: CascaderOption[]
}//本地地址json newprovince.json
export interface JsonAddr {name: stringcode: stringchildren?: JsonAddr[]
}

2.3 TextStyleModifier.ets 自定义字体 (不重要、可以不用加、只需要删除text中的.attributeModifier(xxxxx)属性即可)

export class TextStyleModifier implements AttributeModifier<TextAttribute> {fontSize?: number | string | ResourcefontColor?: ResourceColorfontFamily?: string | Resource | FontDiy = FontDiy.UNSETisPreview :boolean = falseconstructor(fontSize: number | string | Resource,fontColor?: ResourceColor,fontFamily?: string | Resource| FontDiy,isPreview:boolean = false) {this.fontSize = fontSizethis.fontColor = fontColorthis.fontFamily = fontFamilythis.isPreview = isPreview}applyNormalAttribute(instance: TextAttribute): void {if (this.fontSize !== undefined) {instance.fontSize(this.fontSize)}if (this.fontColor !== undefined) {instance.fontColor(this.fontColor)}if (this.fontFamily !== undefined) {//枚举类型if (this.isFontDiy(this.fontFamily)) {if(this.isPreview) {return}switch (this.fontFamily) {case FontDiy.REGULAR:// 处理 REGULARinstance.fontFamily($r('[base].media.pf_regular'))breakcase FontDiy.MEDIUM:instance.fontFamily($r('[base].media.pf_medium'))// 处理 MEDIUMbreakcase FontDiy.SEMI_BOLD:instance.fontFamily($r('[base].media.pf_semibold'))// ...breakdefault:// 默认处理instance.fontFamily($r('[base].media.youshebiaotihei'))break}} else {//不确定是否有问题instance.fontFamily(`${this.fontFamily}`)}}}// 类型守卫函数isFontDiy(value: string | Resource | FontDiy): boolean {return Object.values(FontDiy).includes(value as FontDiy);}
}export enum FontDiy {UNSET,REGULAR,MEDIUM,SEMI_BOLD,YOU_SHE_BIAO_TIHEI
}

2.4 PickerGlobalFun.ets

//地址选择器
export async function showAreaPicker(uiContext: UIContext, call?: (province: JsonAddr, city: JsonAddr,county: JsonAddr,addressInfo:string) => void) {//去读本地数据数据let areaData = await AreaDataUtil.loadJsonFile(getContext())GlobalAreaPicker.show(uiContext, {areaData: areaData,onConfirm:call,})
}

相关代码基本就这么多、加到自己工程里、需要自己稍微调整下 部分变量如IS_PREVIEW找不到可以使用false代替

别大意=》(注意文件类型、注意文件类型、注意文件类型 如ets/ts

3、json地址文件

文件地址:https://download.csdn.net/download/BirdEatBug/91801354

至此基本over

扩展:

1、环境

硬件环境:DevEco Studio 5.0.0

鸿蒙sdk版本(Compatible Sdk):12 

2、json数据源是否可以自定义?

可以
放心目前用的也就是最近两三年的地址json、当然有的需求不一样需要用自己的服务器的地址json

只需要调整JsonAddr 就行了(同时修改AreaPickerContent 所涉及的JsonAddr 字段即可)

修改JsonAddr参考AreaDataUtils 中

let ja = JSON.parse(jsonStr) as JsonAddr[]//改成自己定义的接口就行。
//原来数据源定义如下、可按照需求调整
export interface JsonAddr {name: string// 省市区 名称code: string//对应如上的地址编码children?: JsonAddr[]//市区/市县
}

3、是否有推荐的第三方地址json库

这个:OpenHarmony三方库中心仓 

github:https://github.com/ibestservices/area-data 这两个是同一个库、地址维护比较新        
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/97508.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/97508.shtml
英文地址,请注明出处:http://en.pswp.cn/diannao/97508.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

YOLO 目标检测:数据集构建(LabelImg 实操)、评估指标(mAP/IOU)、 NMS 后处理

文章目录基本知识介绍1.视觉处理三大任务2.训练、验证、测试、推理3.数据集3.1 数据集格式3.2 数据集标注4.上游任务和下游任务YOLO指标1.真实框&#xff08;Ground Truth Box&#xff09;与边界框&#xff08;Bounding Box&#xff09;2.交并比&#xff08;IOU&#xff09;3.置…

进程状态 —— Linux内核(Kernel)

&#x1f381;个人主页&#xff1a;工藤新一 &#x1f50d;系列专栏&#xff1a;C面向对象&#xff08;类和对象篇&#xff09; &#x1f31f;心中的天空之城&#xff0c;终会照亮我前方的路 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 文章目录进…

计算机视觉与深度学习 | 低照度图像处理算法综述:发展、技术与趋势

文章目录 一、发展历程:从传统模型到智能融合 (一)传统模型构建阶段(1970s-2016) (二)深度学习应用阶段(2017-2020) (三)硬件-算法协同阶段(2021至今) 二、技术分类与性能对比 (一)传统方法体系 (二)深度学习方法 1. 监督学习模型 2. 无监督/自监督方法 3. 混…

责任链模式实践-开放银行数据保护及合规

责任链模式介绍什么是责任链模责任链模式是一种行为设计模式&#xff0c; 允许你将请求沿着处理者链进行发送。 收到请求后&#xff0c; 每个处理者均可对请求进行处理&#xff0c; 或将其传递给链上的下个处理者。责任链模式结构伪代码基于责任链的开放银行数据保护及合规实践…

npm install --global @dcloudio/uni-cli 时安装失败

这个日志显示在执行 npm install --global dcloudio/uni-cli 时安装失败&#xff0c;核心错误是 UNABLE_TO_GET_GET_ISSUER_CERT_LOCALLY&#xff08;无法获取本地颁发者证书&#xff09;&#xff0c;属于 HTTPS 证书验证失败 问题。错误原因npm 访问官方 registry&#xff08;…

吱吱企业通讯软件可私有化部署,构建安全可控的通讯办公平台

在当今激烈的市场竞争环境中&#xff0c;企业通讯已成为制胜的关键因素。吱吱作为一款专为企业管理设计的IM即时办公通讯软件&#xff0c;提供了高度安全的通讯办公环境&#xff0c;确保信息在内部流通的安全性与高效性&#xff0c;为企业数字化转型奠定了坚实的基础。 一、私有…

暄桐:唯有认真思考过死亡,才足以应对日常

暄桐是一间传统美学教育教室&#xff0c;创办于2011年&#xff0c;林曦是创办人和授课老师&#xff0c;教授以书法为主的传统文化和技艺&#xff0c;皆在以书法为起点&#xff0c;亲近中国传统之美&#xff0c;以实践和所得&#xff0c;滋养当下生活。初听庄子在妻子离世后“鼓…

目标检测领域基本概念

基于提议的方法&#xff0c;也常被称为两阶段 (Two-stage) 方法&#xff0c;是目标检测领域的经典范式。它们将目标检测任务分解为两个主要步骤&#xff1a;阶段一&#xff1a;区域提议 (Region Proposal Generation) 目标&#xff1a; 在图像中生成一系列可能包含物体的候选区…

【开题答辩全过程】以 基于SpringBoot的流浪猫狗领养系统为例,包含答辩的问题和答案

个人简介一名14年经验的资深毕设内行人&#xff0c;语言擅长Java、php、微信小程序、Python、Golang、安卓Android等开发项目包括大数据、深度学习、网站、小程序、安卓、算法。平常会做一些项目定制化开发、代码讲解、答辩教学、文档编写、也懂一些降重方面的技巧。感谢大家的…

扣子(coze)实践指南进阶篇——创建工作流,并将工作流接入智能体

大家好&#xff0c;欢迎阅读这份《智能体&#xff08;AIAgent&#xff09;开发指南》&#xff01; 在大模型和智能体快速发展的今天&#xff0c;很多朋友希望学习如何从零开始搭建一个属于自己的智能体。本教程的特点是 完全基于国产大模型与火山推理引擎实现&#xff0c;不用翻…

【STM32】外部中断(上)

【STM32】外部中断前言一、中断系统1.1 什么是中断1.2 中断优先级1.3 中断嵌套1.4 中断执行流程二、NVIC2.1NVIC基本结构2.2 NVIC优先级分组三、EXTI3.1 EXTI 外部中断&#xff08;Extern Interrupt&#xff09;3.2 EXTI基本结构3.3 AFIO复用IO口3.4 EXTI内部框图前言 【STM32…

TimeDP Learning to Generate Multi-Domain Time Series with Domain Prompts论文阅读笔记

TimeDP Learning to Generate Multi-Domain Time Series with Domain Prompts 摘要 在跨域时序数据生成任务中&#xff0c;提出使用”时间序列语义原型“模块定义时间序列原型来表示时间序列基&#xff0c;每个原型向量作为“词”表示一些基本的时间序列特征。应用原型分配模块…

Ubuntu安装NVIDIA显卡驱动

清理旧驱动 sudo apt purge nvidia* libnvidia* sudo apt autoremovesudo find /etc -name *nvidia* -exec sudo rm -rf {} sudo rm -rf /usr/local/cuda*禁用 nouveau echo blacklist nouveau options nouveau modeset0 | sudo tee /etc/modprobe.d/blacklist-nouveau.conf…

硬件工程师成长之路:从入门到精通的技术旅程

文章目录前言第一阶段&#xff1a;基础知识的积累理论知识储备动手实践第二阶段&#xff1a;专业技能的提升PCB设计嵌入式系统开发第三阶段&#xff1a;专业方向的选择射频&#xff08;RF&#xff09;工程电源设计高速数字电路FPGA/ASIC设计第四阶段&#xff1a;工程管理与视野…

PyTorch 张量(Tensor)详解:从基础到实战

1. 引言在深度学习和科学计算领域&#xff0c;张量&#xff08;Tensor&#xff09; 是最基础的数据结构。PyTorch 作为当前最流行的深度学习框架之一&#xff0c;其核心计算单元就是张量。与 NumPy 的 ndarray 类似&#xff0c;PyTorch 张量支持高效的数值计算&#xff0c;但额…

CPTS---Hospital

端口扫描 nmap -A -p- -n -Pn -T4 10.10.11.241 22/tcp open ssh OpenSSH 9.0p1 Ubuntu 1ubuntu8.5 (Ubuntu Linux; protocol 2.0) | ssh-hostkey: | 256 e1:4b:4b:3a:6d:18:66:69:39:f7:aa:74:b3:16:0a:aa (ECDSA) |_ 256 96:c1:dc:d8:97:20:95:e7:01:5…

【贪心算法】day5

&#x1f4dd;前言说明&#xff1a; 本专栏主要记录本人的贪心算法学习以及LeetCode刷题记录&#xff0c;按专题划分每题主要记录&#xff1a;&#xff08;1&#xff09;本人解法 本人屎山代码&#xff1b;&#xff08;2&#xff09;优质解法 优质代码&#xff1b;&#xff…

软考中级【网络工程师】第6版教材 第4章 无线通信网 (上)

考点分析: 重要程度:⭐⭐⭐ 选择题考查1 ~ 3分,案例分析可能考查填空和简答 高频考点:802.11信道与频段、CSMA/CA、无线网络优化、无线认证、无线配置步骤 新教材变化:新增4G/5G、删除无线城域网 本章将详述蜂窝移动通信系统、无线局域网以及无线个人网的体系结构和实用技…

vscode+EIDE+Clangd环境导入keil C51以及MDK工程

我最近一直在使用vscodeclangd的编译环境替代了vscode自带的c/c插件。感觉clangd的环境更加优秀&#xff0c;能够更好找到函数、全局变量等定义调用等。如果使用keil C51以及MDK环境开发51单片机或者STM32单片机就需要使用到了EIDE这个插件这个插件现在能够自动生成compile_com…

FTP - 学习/实践

1.应用场景 主要用于学习和使用FTP服务&#xff0c;同时研究其架构实现, 以及日常开发中的使用。 FTP&#xff08;文件传输协议&#xff09;是一种用于网络文件传输的标准协议&#xff0c;基于客户端-服务器模型运行&#xff0c;通过控制通道&#xff08;端口21&#xff09;和…