当前位置: 首页 > news >正文

HarmonyOS Next 省市区级联(三级联动)筛选框

效果图

在这里插入图片描述

完整代码

  • 实例对象
export class ProvinceBean {id?: stringpid?: stringisSelect?: booleandeep?: objectextName?: stringchildren?: ProvinceBean[]
}
  • 级联代码
import { MMKV } from '@tencent/mmkv/src/main/ets/utils/MMKV'
import { ProvinceBean } from '../../../../bean/ProvinceBean'
import { MMKVHelp } from '../../../../util/MMKVHelp'interface CascadeInterface {onClick?: (provinc: ProvinceBean) => voidclose?: () => void
}@Preview
@CustomDialog
export struct CascadeDialog {controller: CustomDialogControllerscrollerOne: Scroller = new Scroller()scrollerTwo: Scroller = new Scroller()scrollerThree: Scroller = new Scroller()callback?: CascadeInterface@State provinceList: ProvinceBean[] = new Array<ProvinceBean>()@State cityList: ProvinceBean[] = new Array<ProvinceBean>()@State areaList: ProvinceBean[] = new Array<ProvinceBean>()@State selectId: string = ''// 记录上次选择的数据在列表中的下标,显示数据时,自动滚动到可见位置@State provinceIndex: number = 0@State cityIndex: number = 0@State areaIndex: number = 0// 跟随父级 改变数据@Prop provinceItem: ProvinceBean = new ProvinceBean()// 临时记录省级数据@State tempProvinceItem: ProvinceBean = new ProvinceBean()aboutToAppear() {let data = MMKV.defaultMMKV().decodeString(MMKVHelp.KEY_CITY)if (data) {this.selectId = this.provinceItem.id ? this.provinceItem.id : ''this.provinceList = JSON.parse(data)if (this.provinceList) {this.provinceList.forEach((provinceBean, provinceIndex) => {if (provinceBean.id == this.selectId) {this.provinceIndex = provinceIndex// 展开式 同步最新省级临时数据this.tempProvinceItem = provinceBeanprovinceBean.isSelect = truethis.cityList = provinceBean.children ? provinceBean.children : new Array<ProvinceBean>()/*** @Desc 一级列表匹配上 2种场景的点击* 二级列表点击:1.全省 2.直辖市*/this.cityList[0].isSelect = true} else {provinceBean.isSelect = falseprovinceBean.children?.forEach((cityBean, cityIndex) => {if (cityBean.id == this.selectId) {this.cityIndex = cityIndexthis.provinceIndex = provinceIndex// 展开时,同步省级对应的数据this.tempProvinceItem = provinceBeanprovinceBean.isSelect = truecityBean.isSelect = truethis.cityList = provinceBean.children ? provinceBean.children : new Array<ProvinceBean>()this.areaList = cityBean.children ? cityBean.children : new Array<ProvinceBean>()/*** @Desc 二级列表匹配上 存在4种场景的点击* 1.全省 2.直辖市 3.直辖市下的区 4.三级列表的全市(第一条)*/if (cityBean.children && cityBean.children.length > 0) { //第4种场景:this.areaList[0].isSelect = true} else {// 直辖市下的区console.log('直辖市下的区' + cityBean.extName)}} else {cityBean.isSelect = falsecityBean.children?.forEach((areaBean, areaIndex) => {if (areaBean.id == this.selectId) {this.areaIndex = areaIndexthis.cityIndex = cityIndexthis.provinceIndex = provinceIndexconsole.log('--22222---' + this.provinceIndex + ' = ' + this.cityIndex + ' = ' + this.cityIndex)// 展开时,同步省对应的数据this.tempProvinceItem = provinceBeanareaBean.isSelect = trueprovinceBean.isSelect = truecityBean.isSelect = truethis.cityList = provinceBean.children ? provinceBean.children : new Array<ProvinceBean>()this.areaList = cityBean.children ? cityBean.children : new Array<ProvinceBean>()} else {areaBean.isSelect = false}})}})}})}}}build() {Column() {Row() {List({ scroller: this.scrollerOne }) {ForEach(this.provinceList, (provinceItem: ProvinceBean, index: number) => {ListItem() {Text(provinceItem.extName).width('100%').fontColor(provinceItem.isSelect ? '#007FFF' : '#FF000000').fontSize(12).padding({ left: 10, top: 10, bottom: 10 })}.onClick(() => {if (provinceItem.isSelect) {console.log('点击的相同地区' + provinceItem.extName)return} else {this.cityList.forEach(item => {item.isSelect = false})this.areaList.forEach(item => {item.isSelect = false})this.areaList = new Array<ProvinceBean>()}this.tempProvinceItem = provinceItemthis.upProvinceList(provinceItem)this.cityList = provinceItem.children ? provinceItem.children : new Array<ProvinceBean>()})})}.layoutWeight(1).backgroundColor(Color.White).height('100%').onSizeChange(() => {this.scrollerOne.scrollToIndex(this.provinceIndex)})List({ scroller: this.scrollerTwo }) {ForEach(this.cityList, (cityItem: ProvinceBean, KEY) => {ListItem() {Text(cityItem.extName).width('100%').fontColor(cityItem.isSelect ? '#007FFF' : '#FF000000').fontSize(12).padding({ left: 10, top: 10, bottom: 10 })}.onClick(() => {// cityItem.children :无数据说明是直辖市/省 ,有数据说明是市下的区if (cityItem.children && cityItem.children.length > 0) { // 切换省下面的市this.upCityList(cityItem)if (!cityItem.isSelect) {this.areaList.forEach(item => {item.isSelect = false})}this.areaList = cityItem.children ? cityItem.children : new Array<ProvinceBean>()} else {//直辖市/省this.callback?.onClick!(cityItem)}})})}.layoutWeight(1).backgroundColor('#F6F6F6').height('100%').onSizeChange(() => {this.scrollerTwo.scrollToIndex(this.cityIndex)})List({ scroller: this.scrollerThree }) {ForEach(this.areaList, (areaItem: ProvinceBean, KEY) => {ListItem() {Text(areaItem.extName).width('100%').fontColor(areaItem.isSelect ? '#007FFF' : '#FF000000').fontSize(12).padding({ left: 10, top: 10, bottom: 10 })}.onClick(() => {this.callback?.onClick!(areaItem)})})}.layoutWeight(1).backgroundColor('#F0F0F0').height('100%').onSizeChange(() => {this.scrollerThree.scrollToIndex(this.areaIndex)})}.alignItems(VerticalAlign.Top).width('100%').height(500)}.onClick(() => {this.controller?.close!()}).backgroundColor("#90000000").height('100%')}/*** @Desc 更新省:自身列表的ui状态*/private upProvinceList(provinceItem: ProvinceBean) {let temp = this.provinceListtemp.forEach(item => {if (provinceItem.id == item.id) {item.isSelect = true} else {item.isSelect = false}})this.provinceList = new Array<ProvinceBean>()this.provinceList = temp}/*** @Desc 更新城市:自身列表的ui状态*/private upCityList(itemBean: ProvinceBean) {let temp = this.cityListtemp.forEach(item => {if (itemBean.id == item.id) {item.isSelect = true} else {item.isSelect = false}})this.cityList = new Array<ProvinceBean>()this.cityList = temp}
}
  • 使用
 @State provinceItem: ProvinceBean = new ProvinceBean()this.controller = new CustomDialogController({builder: CascadeDialog({provinceItem: this.provinceItem,callback: {onClick: (province: ProvinceBean) => {console.log(JSON.stringify(province))this.provinceItem = provincethis.controller?.close()}}}),cancel: () => {this.controller?.close()},offset: { dx: 0, dy: this.postionY },// 弹窗的偏移量autoCancel: true,customStyle: true,maskColor: Color.Transparent,openAnimation: { duration: 0 },closeAnimation: { duration: 0 }});this.controller.open()
  • 获取点击组件,组件底部距离屏幕顶部的高度
.onClick((event: ClickEvent) => {this.postionY = Number(event.target.area.height) + Number(event.target.area.globalPosition.y)  })

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Golang AES 对称加密
  • Flutter开发Dart 中的 mixin、extends 和 implements
  • Linux--网络基础
  • 设计模式 之 —— 单例模式
  • 数据库系列
  • ZLMRTCClient配置说明与用法(含示例)
  • web前端 React 框架面试200题(三)
  • pytest+allure
  • 《Java初阶数据结构》----4.<线性表---Stack栈和Queue队列>
  • vue上传Excel文件并直接点击文件列表进行预览
  • 学习笔记10:bos、cos和对象存储 的区别
  • yarn的安装与配置
  • 身份证如何查验真伪?C#身份证二要素、三要素接口集成
  • BACnet物联网关BL103:Modbus协议转BACnet/MSTP
  • 2024秋招算法
  • log4j2输出到kafka
  • maya建模与骨骼动画快速实现人工鱼
  • react 代码优化(一) ——事件处理
  • react-native 安卓真机环境搭建
  • vuex 学习笔记 01
  • 阿里研究院入选中国企业智库系统影响力榜
  • 关于使用markdown的方法(引自CSDN教程)
  • 使用 5W1H 写出高可读的 Git Commit Message
  • 策略 : 一文教你成为人工智能(AI)领域专家
  • ​1:1公有云能力整体输出,腾讯云“七剑”下云端
  • !!Dom4j 学习笔记
  • # windows 安装 mysql 显示 no packages found 解决方法
  • #设计模式#4.6 Flyweight(享元) 对象结构型模式
  • #我与Java虚拟机的故事#连载10: 如何在阿里、腾讯、百度、及字节跳动等公司面试中脱颖而出...
  • (Java数据结构)ArrayList
  • (Python第六天)文件处理
  • (八)Flink Join 连接
  • (附源码)ssm高校实验室 毕业设计 800008
  • (蓝桥杯每日一题)平方末尾及补充(常用的字符串函数功能)
  • (三)Kafka 监控之 Streams 监控(Streams Monitoring)和其他
  • (四)React组件、useState、组件样式
  • (学习日记)2024.04.10:UCOSIII第三十八节:事件实验
  • (转)用.Net的File控件上传文件的解决方案
  • .bat批处理(二):%0 %1——给批处理脚本传递参数
  • .net 流——流的类型体系简单介绍
  • .Net7 环境安装配置
  • .sh
  • @JSONField或@JsonProperty注解使用
  • @Transactional类内部访问失效原因详解
  • [ Algorithm ] N次方算法 N Square 动态规划解决
  • [ 转载 ] SharePoint 资料
  • [.NET]桃源网络硬盘 v7.4
  • [AIGC] MySQL存储引擎详解
  • [Algorithm][综合训练][kotori和n皇后][取金币][矩阵转置]详细讲解
  • [BT]BUUCTF刷题第8天(3.26)
  • [BUG]Datax写入数据到psql报不能序列化特殊字符
  • [BZOJ]4817: [Sdoi2017]树点涂色
  • [BZOJ4566][HAOI2016]找相同字符(SAM)
  • [dart学习]第四篇:函数
  • [ffmpeg] x264 配置参数解析