欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 美景 > HarmonyOS Next 省市区级联(三级联动)筛选框

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

2024/10/24 9:26:14 来源:https://blog.csdn.net/qq_34501274/article/details/140669792  浏览:    关键词: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)  })

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com