尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

Android开发 Jetpack_Compose DatePickerBottomSheet 滚轮日历选择器对话框

Android开发 Jetpack_Compose DatePickerBottomSheet 滚轮日历选择器对话框
📅 发布时间:2026/6/19 1:00:24
Android开发 Jetpack_Compose DatePickerBottomSheet 滚轮日历选择器对话框

声明

本文来自博客园,作者:观心静 ,转载请注明原文链接:https://www.cnblogs.com/guanxinjing/p/19316238

本文版权归作者和博客园共有,欢迎转载,但必须给出原文链接,并保留此段声明,否则保留追究法律责任的权利。

前言

这个日历用了我的博客中另一个compose的自定义滚轮,如果你需要使用它,请先将滚轮View拷贝到项目中,滚轮View的博客地址 Android开发 Jetpack_Compose WheelPicker简单的自定义滚轮选择器 - 观心静 - 博客园

效果图

image

使用

val isShowCalendarDialog = remember { mutableStateOf(false) }
DatePickerBottomSheet(isVisible = isShowCalendarDialog,startDate = Calendar.getInstance().apply { set(1960, 0, 1) },endDate = Calendar.getInstance(),onDateSelected = {val dataFormat = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault())viewModel.userBirthday.value = dataFormat.format( it.timeInMillis)viewModel.updateBtnState()isShowCalendarDialog.value = false},onDismiss = {isShowCalendarDialog.value = false},
)

代码


import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.ModalBottomSheet
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.yakwatch.android.fitvibe.ui.compView.WheelPicker
import java.util.Calendar@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun DatePickerBottomSheet(isVisible: MutableState<Boolean>,initialDate: Calendar = Calendar.getInstance(),startDate: Calendar = Calendar.getInstance().apply { set(1900, 0, 1) },endDate: Calendar = Calendar.getInstance().apply { set(2100, 11, 31) },onDateSelected: (Calendar) -> Unit,onDismiss: () -> Unit
) {if (isVisible.value) {ModalBottomSheet(containerColor = MaterialTheme.colorScheme.surface,dragHandle = null,onDismissRequest = onDismiss) {var selectedYear by remember { mutableIntStateOf(initialDate.get(Calendar.YEAR)) }var selectedMonth by remember { mutableIntStateOf(initialDate.get(Calendar.MONTH) + 1) }var selectedDay by remember { mutableIntStateOf(initialDate.get(Calendar.DAY_OF_MONTH)) }// 限制年份范围val startYear = startDate.get(Calendar.YEAR)val endYear = endDate.get(Calendar.YEAR)val years = (startYear..endYear).map { it.toString() }// 限制月份范围(根据年份动态调整)val months = if (selectedYear == startYear && selectedYear == endYear) {// 同一年,月份受限于开始和结束月份(startDate.get(Calendar.MONTH) + 1..endDate.get(Calendar.MONTH) + 1).map { it.toString() }} else if (selectedYear == startYear) {// 等于开始年份,月份从开始月份到最后一个月(startDate.get(Calendar.MONTH) + 1..12).map { it.toString() }} else if (selectedYear == endYear) {// 等于结束年份,月份从1月到结束月份(1..endDate.get(Calendar.MONTH) + 1).map { it.toString() }} else {// 中间年份,月份不受限(1..12).map { it.toString() }}// 根据年月动态计算天数,并应用日期范围限制val daysInMonth = getDaysInMonth(selectedYear, selectedMonth)val days =if (selectedYear == startYear && selectedMonth == startDate.get(Calendar.MONTH) + 1) {// 等于开始年月,日期从开始日期到最后一天(startDate.get(Calendar.DAY_OF_MONTH)..daysInMonth).map { it.toString() }} else if (selectedYear == endYear && selectedMonth == endDate.get(Calendar.MONTH) + 1) {// 等于结束年月,日期从1号到结束日期(1..endDate.get(Calendar.DAY_OF_MONTH)).map { it.toString() }} else {// 其他情况,日期不受限(1..daysInMonth).map { it.toString() }}Column(modifier = Modifier.fillMaxWidth(),horizontalAlignment = Alignment.CenterHorizontally) {Spacer(modifier = Modifier.height(24.dp))Row(modifier = Modifier.fillMaxWidth().padding(horizontal = 36.dp),horizontalArrangement = Arrangement.SpaceBetween,verticalAlignment = Alignment.CenterVertically) {Text("取消",style = MaterialTheme.typography.bodyMedium,color = MaterialTheme.colorScheme.onBackground,modifier = Modifier.clickable(onClick = onDismiss))Text(text = "选择日期",style = MaterialTheme.typography.titleMedium,)Text("确定",style = MaterialTheme.typography.bodyMedium,color = MaterialTheme.colorScheme.primary,modifier = Modifier.clickable(onClick = {val calendar = Calendar.getInstance().apply {set(selectedYear, selectedMonth - 1, selectedDay)}// 验证选择的日期是否在范围内if (calendar.timeInMillis >= startDate.timeInMillis &&calendar.timeInMillis <= endDate.timeInMillis) {onDateSelected(calendar)}}))}Spacer(modifier = Modifier.height(24.dp))Row(modifier = Modifier.fillMaxWidth(),horizontalArrangement = Arrangement.SpaceEvenly) {// 年份选择器Column(modifier = Modifier.weight(1f),horizontalAlignment = Alignment.CenterHorizontally) {WheelPicker(items = years,defaultSelectedIndex = years.indexOf(selectedYear.toString()).coerceAtLeast(0).coerceAtMost(years.size - 1),onSelectedIndex = { index ->selectedYear = years[index].toInt()},itemHeight = 40.dp,itemFontSize = 18.sp,visibleItemsCount = 5)}// 月份选择器Column(modifier = Modifier.weight(1f),horizontalAlignment = Alignment.CenterHorizontally) {WheelPicker(items = months,defaultSelectedIndex = months.indexOf(selectedMonth.toString()).coerceAtLeast(0).coerceAtMost(months.size - 1),onSelectedIndex = { index ->selectedMonth = months[index].toInt()},itemHeight = 40.dp,itemFontSize = 18.sp,visibleItemsCount = 5)}// 日期选择器Column(modifier = Modifier.weight(1f),horizontalAlignment = Alignment.CenterHorizontally) {WheelPicker(items = days,defaultSelectedIndex = days.indexOf(selectedDay.toString()).coerceAtLeast(0).coerceAtMost(days.size - 1),onSelectedIndex = { index ->selectedDay = days[index].toInt()},itemHeight = 40.dp,itemFontSize = 18.sp,visibleItemsCount = 5)}}Spacer(modifier = Modifier.height(24.dp))}}}
}private fun getDaysInMonth(year: Int, month: Int): Int {val calendar = Calendar.getInstance().apply {set(Calendar.YEAR, year)set(Calendar.MONTH, month - 1)set(Calendar.DAY_OF_MONTH, 1)}return calendar.getActualMaximum(Calendar.DAY_OF_MONTH)
}

 

end

本文来自博客园,作者:观心静 ,转载请注明原文链接:https://www.cnblogs.com/guanxinjing/p/19316238

本文版权归作者和博客园共有,欢迎转载,但必须给出原文链接,并保留此段声明,否则保留追究法律责任的权利。

相关新闻

  • 代码资源空间调整:当前代码与资源的总大小超过FLASH的大小,需要更大的FLASH
  • 亚马逊发起新的Alexa Prize SimBot挑战
  • 制造业图文档收发的安全交换解决方案分析

最新新闻

  • KES 数据库迁移实战:从 Oracle/MySQL 到 KingbaseES 的平滑过渡指南
  • LangGraph重试策略:如何构建高可靠的AI工作流自动恢复机制
  • 深入解析MPC850FADS子板:PowerPC嵌入式开发硬件设计与调试实战
  • MQX RTOS MFS嵌入式文件系统:原理、API实战与性能调优指南
  • Python+Appium移动端自动化测试:从环境搭建到框架优化的完整实战指南
  • AI向善不是加个loss函数:社会价值项目的全链路实操指南

日新闻

  • 5分钟掌握Python进化算法:Geatpy高性能优化工具完全指南
  • Microchip 24AA044 EEPROM选型与应用全指南:从参数解析到实战编程
  • 华为的鸿蒙到底有多牛?为什么称作遥遥领先?

周新闻

  • 3步解锁iOS设备:applera1n激活锁绕过完全指南
  • 39 2026 人工智能证书终极盘点,普通人选 AI 证书可以从这些方向入手
  • Redis 暴露公网有多危险?从端口检查到补救步骤

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号