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

使用compose和WheelView实现仿IOS中的3D滚轮控件-三级联动

文章目录

  • 1、资源准备:
  • 2、实现效果
  • 3、导入wheelview模块
    • 3.1 问题与解决
      • 3.1.1 问题1-插件找不到
        • 解决:
      • 3.1.2 问题2-未定义内存空间namespace
    • 3.2 添加依赖
  • 4、解析json文件
  • 4.1 修改json文件
  • 4.2 转换json文件中数据
  • 5、使用compose实现省市区三级联动
  • 5.1 展示WheelView控件
  • 5.2 compose实现省市区三级联动
  • 5.3 处理json数据并进行展示

1、资源准备:

① 省-市-区/县 三级资源下载
② wheelView依赖模板下载
在资源②中,下载后,将其中的wheelview模块通过Import Module from Source导入自己的项目中。

2、实现效果

在这里插入图片描述

3、导入wheelview模块

3.1 问题与解决

3.1.1 问题1-插件找不到

问题:
在导入wheelview后,会出现找不到com.github.dcendents.android-maven的问题

解决:

在wheelview模块的build.gradle中将
apply plugin: ‘com.github.dcendents.android-maven’
修改为

apply plugin: 'maven-publish'

3.1.2 问题2-未定义内存空间namespace

在build.gradle的android {}中添加代码

     namespace =  "com.contrarywind.view"

3.2 添加依赖

在app的buid.gradle中添加

 implementation(project(":wheelview"))

4、解析json文件

4.1 修改json文件

将下载的json资源文件存放在assets文件夹中,并修改json文件为DistrictCityJson.json,结构为

{"data_version": "1.0.0","districts":
{
{"北京市":{"市辖区":["东城区" //为下载的资源文件,也可以不修改,那就需要将下方数据转换的数据结构修改一下
}

的形式。

4.2 转换json文件中数据

创建需要的数据结构,其中RegionData表示的是获取json的数据结构,可通过Gson().fromJson方法将json文件转为实体数据。
RegionResponse为后续方便使用的数据结构,层次结构,方便wheelView使用

data class RegionData(val data_version: String,val districts: Map<String, Map<String, List<String>>>
)
data class RegionResponse(val data_version: String,val districts: List<District>
)data class District(val name: String,val level: Int,         // 1:省/直辖市 2:市 3:区县val districts: List<District>  = emptyList()
)object RegionDataParser {// 方法1:直接解析为Map结构fun parseRegionDataFromAssets(context: Context, fileName: String): RegionData {return try {val jsonString = context.assets.open(fileName).bufferedReader().use { it.readText() }Gson().fromJson(jsonString, RegionData::class.java)} catch (e: IOException) {throw RuntimeException("Could not read $fileName from assets", e)}}//方法2:将原始数据转为层级的结构fun parseStructuredRegionsFromAssets(context: Context, fileName: String): RegionResponse {val originalList : RegionData =  parseRegionDataFromAssets(context,fileName)return RegionResponse(data_version = originalList.data_version,districts = originalList.districts.map { (provinceName, citiesMap) ->District(name = provinceName,level = 1,districts = citiesMap.map { (cityName, districtsList) ->District(name = cityName,level = 2,districts = districtsList.map { districtName ->District(name = districtName,level = 3)})})})}
}

5、使用compose实现省市区三级联动

5.1 展示WheelView控件

WheelView控件在AndroidView中进行初始化和更新的操作,在初始化之前创建其适配器,该适配器在列表变化时重新加载,在

@Composable
fun GetWheelView(modifier: Modifier = Modifier,wheelViewList:List<String> =  listOf("北京市","天津市"),onSelected: (String) -> Unit = {}
){val selectedPosition = remember { mutableStateOf(0) }val wheelAdapter =  remember(wheelViewList) {object : WheelAdapter<String>{override fun getItemsCount(): Int {return wheelViewList.size}override fun getItem(index: Int): String {return wheelViewList[index]}override fun indexOf(o: String?): Int {return wheelViewList.indexOf(o)}}}AndroidView(modifier = modifier.padding(dimensionResource(R.dimen.padding_top_5)).width(dimensionResource(R.dimen.box_width_100)),factory = {contex->WheelView(contex).apply {setCyclic(false)setDividerType(WheelView.DividerType.WRAP)setCurrentItem(0)setItemsVisibleCount(10)setTextColorCenter(0xFFB11C1E.toInt())setTextSize(18f)setAlphaGradient(false)adapter = wheelAdapter}},update = { wheelView->wheelView.adapter = wheelAdapter// 添加选中监听器以更新状态wheelView.setOnItemSelectedListener { position ->selectedPosition.value = positionLog.d(TAG, "GetWheelView: ${wheelViewList[position]}")onSelected.invoke(wheelViewList[position])}})
}

5.2 compose实现省市区三级联动

@Preview
@Composable
fun AddressPickerScreen(onDismiss: () -> Unit = {},districtsList: List<District> = listOf(District(name = "北京市",level = 1,districts = listOf(District(name = "市辖区",level = 2,districts = listOf(District(name = "丰台区", level = 3))))),District(name = "北京市",level = 1,districts = listOf(District(name = "市辖区",level = 2,districts = listOf(District(name = "西城区", level = 3))))),),onConfirm: (String, String, String) -> Unit = { _, _, _ ->}
) {// 状态管理var selectedProvince by remember { mutableStateOf<District?>(null) }var selectedCity by remember { mutableStateOf<District?>(null) }var selectedDistrict by remember { mutableStateOf<District?>(null) }// 数据列表val provinces = remember { mutableStateListOf<District>() }val cities = remember { mutableStateListOf<District>() }val districts = remember { mutableStateListOf<District>() }// 初始化加载省份数据LaunchedEffect(Unit) {provinces.clear()provinces.addAll(districtsList)selectedProvince = provinces[0]}// 当省份变化时加载城市LaunchedEffect(selectedProvince) {selectedProvince?.let { province ->cities.clear()cities.addAll(districtsList.find { it.name == province.name }?.districts?: listOf())selectedCity = cities[0]selectedDistrict = cities[0].districts[0]} ?: run {cities.clear()districts.clear()}}// 当城市变化时加载区县LaunchedEffect(selectedCity) {selectedCity?.let { city ->districts.clear()districts.addAll(cities.find { it.name == city.name }?.districts?: listOf())selectedDistrict = districts[0]} ?: run {districts.clear()}}// 对话框UIDialog(onDismissRequest = onDismiss) {Column(modifier = Modifier.fillMaxWidth().background(Color.White)) {Row(modifier = Modifier.fillMaxWidth()) {TextButton(modifier = Modifier.weight(5f),onClick = {onDismiss()},enabled = true) {Text("取消", color = Color.Blue)}TextButton(modifier = Modifier.weight(5f),onClick = {onConfirm(selectedProvince?.name ?: "",selectedCity?.name ?: "",selectedDistrict?.name ?: "")},enabled = selectedDistrict != null) {Text("确定", color = Color.Blue)}}// 三级联动选择区域Row(modifier = Modifier.fillMaxWidth()) {// 省份列表GetWheelView(wheelViewList = provinces.map { it.name },onSelected = {selectedProvince  = selectedProvince?.copy(name = it)})// 城市列表(当有省份选中时显示)if (selectedProvince != null) {GetWheelView(wheelViewList = cities.map { it.name },onSelected = {selectedCity  = selectedCity?.copy(name = it)})}// 区县列表(当有城市选中时显示)if (selectedCity != null) {GetWheelView(wheelViewList = districts.map { it.name },onSelected = {selectedDistrict  = selectedDistrict?.copy(name = it)})}}}}
}

5.3 处理json数据并进行展示

@Preview
@Composable
fun PickWheelView(){val context = LocalContext.currentval districtsList =  RegionDataParser.parseStructuredRegionsFromAssets(context,"DistrictCityJson.json")AddressPickerScreen(districtsList = districtsList.districts,onConfirm = {province,city,district->Log.d(TAG, "PickWheelView:$province $city $district ")})
}
http://www.dtcms.com/a/465149.html

相关文章:

  • Burpsuite工具使用
  • 做网站设计电脑需要什么配置企业如何建设网站呢
  • 旅游网站制作内容淘宝网站小视频怎么做的
  • 关于 Qt 6.10.0 中 FolderListModel 返回 undefined 路径
  • 做展会怎么引流到自己的网站小程序生成器
  • 【第五章:计算机视觉-项目实战之生成式算法实战:扩散模型】3.生成式算法实战:扩散模型-(1)从零开始训练自己的扩散模型
  • [VoiceRAG] 集成向量化 | Azure AI Search中建立自动化系统
  • 从效能革命到体验重构,易路 AI Agent 破局 HR 三重困境
  • 计算机视觉(opencv)——基于 OpenCV DNN 的实时人脸检测 + 年龄与性别识别
  • Flink 状态后端(State Backends)实战原理、选型、配置与调优
  • Node.js HTTP开发
  • 在 Mac 上使用 Docker 安装 Milvus 2.6.2
  • 福州市住房和城乡建设部网站wordpress 数据导入
  • 北京网站设计技术wordpress 评论验证
  • 亚马逊测评总踩雷?自养号技术筑牢安全防线,避开封号坑
  • Ubuntu 20.04 使用 Issac Gym 进行宇树G1人形机器人进行强化学习训练(Linux仿真)
  • 制造业工艺文档安全协作与集中管理方案
  • 场景美术师的“无限画板”:UE5中非破坏性的材质混合(Material Blending)工作流
  • 黑马微服务P3快速入门入门案例无法跑通解决方案,本文解决了数据库连接和java版本不匹配的问题
  • 遗留系统微服务改造(三):监控运维与最佳实践总结
  • 四川建设招标网站首页自己做的网站显示不安全怎么回事
  • 网络层协议之OSPF协议
  • vue3+hubuilderX开发微信小程序使用elliptic生成ECDH密钥对遇到的问题
  • 跑马灯组件 Vue2/Vue3/uni-app/微信小程序
  • 网络攻防实战:如何防御DDoS攻击
  • 能力(5)
  • 多模态医疗大模型Python编程合规前置化与智能体持续学习研究(下)
  • wordpress网站不显示系列秦皇岛网站制作与网站建设
  • 【2026计算机毕业设计】基于Springboot的广西美食宣传系统
  • Instagram投放转化率还能再提升!