JetpackCompose封装省市区三级联动选择器

由于最近在写一个compose项目,需要用到省市区三级联动选择器。之前在使用xml写Android的时候,直接拿别人封装好的开源框架十分方便,又不想用别的麻烦操作,全网也找不到一个现有的、合适的框架,于是心血来潮,连夜搓了一个出来。

主要技术难点:

处理数据。级联选择器必不可少的是数据,数据以json文件形式放在assets中,定义函数拿取json数据并解析成指定的"Province"对象

fun loadJsonFromAssets(context: Context, fileName: String): String? {
    return try {
        context.assets.open(fileName).bufferedReader().use { it.readText() }
    } catch (ex: IOException) {
        ex.printStackTrace()
        null
    }
}

fun parseProvinces(jsonString: String): List<Province> {
    return Json.decodeFromString(jsonString)
}

设计滚动列表和控制滚动状态。选择器由BottomSheet三个小的滚轮组成,使用kotlin的协程和StateManagement监听用户交互和处理滚动动画,确定当前选择项和让选择项始终维持在中部位置。

      LaunchedEffect(listState) {
            snapshotFlow { listState.layoutInfo.visibleItemsInfo }
                .map { visibleItems ->
                    val viewportStartOffset = listState.layoutInfo.viewportStartOffset
                    val viewportEndOffset = listState.layoutInfo.viewportEndOffset
                    val viewportCenter = (viewportEndOffset - viewportStartOffset) / 2 + viewportStartOffset

                    visibleItems.minByOrNull {
                        Math.abs((it.offset + it.size / 2) - viewportCenter)
                    }
                }
                .collect { centerItem ->
                    centerItem?.let {
                        centerIndex.value = it.index
                        onItemSelected(it.index)
                    }
                }
        }

        LaunchedEffect(listState) {
            listState.interactionSource.interactions.collect { interaction ->
                when (interaction) {
                    is DragInteraction.Stop, is DragInteraction.Cancel -> {
                        scope.launch {
                            val visibleItems = listState.layoutInfo.visibleItemsInfo
                            val viewportStartOffset = listState.layoutInfo.viewportStartOffset
                            val viewportEndOffset = listState.layoutInfo.viewportEndOffset
                            val viewportCenter = (viewportEndOffset - viewportStartOffset) / 2 + viewportStartOffset

                            val centerItem = visibleItems.minByOrNull {
                                Math.abs((it.offset + it.size / 2) - viewportCenter)
                            }
                            centerItem?.let {
                                listState.animateScrollToItem(it.index)
                                centerIndex.value = it.index
                                onItemSelected(it.index)
                            }
                        }
                    }
                }
            }
        }

使用方法:

//setting.gradle
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
        maven { url 'https://jitpack.io' }
    }
}
//build.gradle(app模块)
implementation 'com.github.simonniex:SimonCityPicker:2.2.0'

//Activity/screen/fragment
val context = LocalContext.current
var selectedCity by remember { mutableStateOf("请选择城市") }
var isCity by remember { mutableStateOf(false) }
Row(
    horizontalArrangement = Arrangement.Center,
    modifier = Modifier.fillMaxWidth().padding(100.dp)
) {
    TextButton(modifier = Modifier.background(Color.Gray),onClick = {
    isCity = true
  }){
    Text(text = selectedCity, color = Color.White)
  }
}
 SimonCityPicker(
      context = context,
      isCity = isCity,
      onCitySelected = { city ->
      selectedCity=city
      isCity = false
 }
 )

效果演示:

总结:

 项目地址:

simonniex/SimonCityPicker: 基于JetpackCompose的省市区级联选择器 (github.com)

本开源库是初代(v2.2.0)版本,如果反响不错,我会持续优化,迭代更新。如果喜欢这个项目可以点赞关注一波,欢迎在评论区交流!

以下是分界线

---------------------------------------------------

注意:

如果你自动注入依赖失败,请手动下载并导入

SimonCityPicker-2.3.0.aar

  • 9
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以通过使用uview组件来实现uni picker省市区三级联动。这个组件可以在uniapp中使用,并且已经封装好了数据的渲染和传递功能。你可以使用template模板语法将数据从页面中传递给uview组件,然后通过Ajax请求从后台获取省市区的数据,将其渲染到picker组件中,并将选择的省市区的code码拼接后传递给后台实现需求。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [使用picker封装省市区三级联动模板](https://download.csdn.net/download/weixin_38642636/16215282)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [uniapp使用uview组件实现省市区三级联动](https://download.csdn.net/download/m0_62676565/85819519)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [uniapp picker组件实现省市区三级联动效果](https://blog.csdn.net/weixin_45356397/article/details/119701421)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值