compose时间滚轮选择器

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)
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值