1.时间滚轮选择器列表
@Composable fun DatePickerColumn( // 列表 pairList: List<Pair<Int, String>>, itemHeight: Dp, itemWidth: Dp? = null, valueState: MutableState<Int>, focusColor: Color = MaterialTheme.colorScheme.primary, unfocusColor: Color = Color(0xFFC5C7CF) ) { var isInit = false val dataPickerCoroutineScope = rememberCoroutineScope() val listState = rememberLazyListState() var value by valueState LazyColumn( state = listState, modifier = Modifier .height(itemHeight * 6) .padding(top = itemHeight / 2, bottom = itemHeight / 2) ) { item { Surface(Modifier.height(itemHeight)) {} } item { Surface(Modifier.height(itemHeight)) {} } itemsIndexed(items = pairList, key = { index, pair -> pair.first }) { index, pair -> val widthModifier = itemWidth?.let { Modifier.width(itemWidth) } ?: Modifier Box( modifier = Modifier .height(itemHeight) .then(widthModifier) .clickable { dataPickerCoroutineScope.launch { listState.animateScrollToItem(index = index) } } .padding(start = 5.dp, end = 5.dp), Alignment.Center ) { Text( text = pair.second, color = if (listState.firstVisibleItemIndex == index) focusColor else unfocusColor ) } } item { Surface(Modifier.height(itemHeight)) {} } item { Surface(Modifier.height(itemHeight)) {} } } if (listState.isScrollInProgress) { LaunchedEffect(Unit) { //只会调用一次,相当于滚动开始 } //当state处于滚动时,preScrollStartOffset会被初始化并记忆,不会再被更改 val preScrollStartOffset by remember { mutableStateOf(listState.firstVisibleItemScrollOffset) } val preItemIndex by remember { mutableStateOf(listState.firstVisibleItemIndex) } val isScrollDown = if (listState.firstVisibleItemIndex > preItemIndex) { //第一个可见item的index大于开始滚动时第一个可见item的index,说明往下滚动了 true } else if (listState.firstVisibleItemIndex < preItemIndex) { //第一个可见item的index小于开始滚动时第一个可见item的index,说明往上滚动了 false } else { //第一个可见item的index等于开始滚动时第一个可见item的index,对比item offset listState.firstVisibleItemScrollOffset > preScrollStartOffset } DisposableEffect(Unit) { onDispose { // 滑动结束时给状态赋值,并自动对齐 if (listState.firstVisibleItemIndex <= pairList.size) { value = pairList[listState.firstVisibleItemIndex].first } dataPickerCoroutineScope.launch { listState.animateScrollToItem(listState.firstVisibleItemIndex) } } } } // 选择初始值 LaunchedEffect(Unit) { var initIndex = 0 for (index in pairList.indices) { if (value == pairList[index].first) { initIndex = index break } } dataPickerCoroutineScope.launch { listState.animateScrollToItem(initIndex) } } }
2.日期时间选择器
这里的vm参数可以去掉,打开里面对应的注释即可
@Composable fun DataTimePicker( date: Date = Date(), vm: CreateEventVM ) { val itemHeight = 50.dp Box( modifier = Modifier .wrapContentHeight() .fillMaxWidth(), Alignment.Center ) { Row( Modifier .wrapContentHeight() .fillMaxWidth() .background(MaterialTheme.colorScheme.surface), Arrangement.SpaceEvenly, Alignment.CenterVertically ) { val year = date.getYearr() // val selectYear = rememberSaveable { mutableStateOf(year) } val years = LinkedList<Pair<Int, String>>().apply { for (i in year..year + 2) { add(Pair(i, "${i}年")) } } DatePickerColumn(years, itemHeight, 70.dp, vm.selectYear) // 月份 val month = date.getMonthh() // val selectMonth = rememberSaveable { mutableStateOf(month) } val months = ArrayList<Pair<Int, String>>(12).apply { for (i in month..12) { add(Pair(i, "${i}月")) } } DatePickerColumn(months, itemHeight, 50.dp, vm.selectMonth) // 月份的天数 val dayOfMon = date.getDayOfMonth() val dayCountOfMonth = DateUtil.getDayCountOfMonth(vm.selectYear.intValue, vm.selectMonth.intValue) // 提前定义好 val day31 = ArrayList<Pair<Int, String>>().apply { for (i in 1..31) add(Pair(i, "${i}日")) } val day30 = ArrayList<Pair<Int, String>>().apply { for (i in 1..30) add(Pair(i, "${i}日")) } val day29 = ArrayList<Pair<Int, String>>().apply { for (i in 1..29) add(Pair(i, "${i}日")) } val day28 = ArrayList<Pair<Int, String>>().apply { for (i in 1..28) add(Pair(i, "${i}日")) } // 快速切换 val dayOfMonList = when (dayCountOfMonth) { 28 -> day28 29 -> day29 30 -> day30 else -> day31 } DatePickerColumn( pairList = dayOfMonList, itemHeight = itemHeight, valueState = vm.selectDay ) // 小时 val hour = date.getHour() val hours = ArrayList<Pair<Int, String>>(24).apply { for (i in 0..23) { add(Pair(i, "${i}时")) } } DatePickerColumn(hours, itemHeight, 50.dp, vm.selectHour) } } }