声明
本文来自博客园,作者:观心静 ,转载请注明原文链接:https://www.cnblogs.com/guanxinjing/p/19316238
本文版权归作者和博客园共有,欢迎转载,但必须给出原文链接,并保留此段声明,否则保留追究法律责任的权利。
前言
这个日历用了我的博客中另一个compose的自定义滚轮,如果你需要使用它,请先将滚轮View拷贝到项目中,滚轮View的博客地址 Android开发 Jetpack_Compose WheelPicker简单的自定义滚轮选择器 - 观心静 - 博客园
效果图

使用
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
本文版权归作者和博客园共有,欢迎转载,但必须给出原文链接,并保留此段声明,否则保留追究法律责任的权利。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/990417.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!相关文章
代码资源空间调整:当前代码与资源的总大小超过FLASH的大小,需要更大的FLASH
1. 提示音
2. 音频解码格式,如AAC、FLAC
3. DRC
4. 调试日志串口
5. 文件isd_config.ini中可调整VM_LEN最小到8K(将无法蓝牙升级)、内置FLASH录音分区(默认没有开辟)
6. 耳机SDK有ANS、DNS算法可关闭
7. TWS、BLE…
亚马逊发起新的Alexa Prize SimBot挑战
某中心宣布推出Alexa Prize SimBot挑战赛,旨在推动下一代虚拟助手技术的发展。挑战聚焦于在虚拟环境中通过自然语言完成导航、物体操控等任务,并发布了用于训练的家庭任务对话数据集TEACh。亚马逊发起新的Alexa Priz…
跨国数据传输解决方案为企业提供安全与合规保障
跨国数据传输的过程中,企业需要面对诸多合规和安全挑战。Ftrans解决方案为这一需求提供了一条清晰的路径。该方案不仅聚焦于数据的入境和出海环节,还全面考虑了法律法规的要求,以确保合规性。同时,Ftrans在实际传输…
数据结构(18) - 实践
数据结构(18) - 实践2025-12-06 17:11
tlnshuju
阅读(0)
评论(0) 收藏
举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font…
题解:qoj5411 杏仁
题意:定义一个图源汇点 \(s,t\) 固定的图为杏仁图,当且仅当可以找到一个路径划分 \(S_1,S_2,\cdots S_k\),使得所有边都在路径中出现且仅出现一次,并且所有路径的交点仅为 \(s,t\)。一个图的杏仁子图定义为为其子图…
游记:CSP2025
FJ 初三考生,今年第四次 CSP,第三次复赛,决定写一篇游记简单记录下。
只报名了 S 组。
初赛
听说 J 组考交互了,感觉 CCF 要干大事。
初赛其实比去年感觉好多了,程序题都能看懂了。 You have no egg 真的很难绷。…
CSP2025 游记
FJ 初三考生,今年第四次 CSP,第三次复赛,决定写一篇游记简单记录下。
只报名了 S 组。
初赛
听说 J 组考交互了,感觉 CCF 要干大事。
初赛其实比去年感觉好多了,程序题都能看懂了。 You have no egg 真的很难绷。…
制造业图文档收发的安全交换解决方案分析
在制造业中,文件安全交换是保障数据完整性与机密性的关键。通过引入Ftrans B2B企业间文件安全交换系统,企业能有效实现与外部合作伙伴之间的安全数据流动。该系统通过伙伴管理、文件外发审核等功能,为企业提供灵活而…
Spring boot 中 CommandLineRunner 在服务启动完成后自定义执行
转载请注明出处:以下是 Spring boot中 CommandLineRunner 的定义:package org.springframework.boot;@FunctionalInterface
public interface CommandLineRunner {void run(String... args) throws Exception;
}Comm…
文件摆渡系统哪个好:提升企业文件交换安全性的首选方案
文件摆渡系统的选择对企业的数字安全至关重要。Ftrans Ferry作为一个先进的文件交换平台,不仅具备强大的安全防护功能,还在企业数据管理上表现出色。其具有多层次的安全措施,包括数据丢失防护(DLP)、实时病毒查杀…
2025年越野轮胎推荐:专业越野胎权威测评
2025年越野轮胎推荐:专业越野胎权威测评在消费者对“2025年越野轮胎推荐”需求日益精细化的当下,如何在兼顾城市通勤与轻度越野全场景的前提下,挑选出一款在极限安全、动态操控、驾乘舒适与全生命周期价值四大维度均…
115.娇三“独处-再思考”
115.娇三“独处-再思考”2025.12.6日一站式自习室下午四刻左右记
每一到冬季,大概11-12月就要犯一次病,说不上是感冒大概是脑袋糊了一层膜,很多事情都似感觉不真实,不过初高中那时吓人在于心态上不如现在,那时确实…
2025最新发布!耐磨的轮胎推荐:五大高耐磨胎精选报告
2025最新发布!耐磨的轮胎推荐:五大高耐磨胎精选报告在轮胎消费决策体系中,耐磨性能始终是撬动用户长期价值感知的关键支点。尤其对于运营车队管理者与高频长途驾驶群体而言,轮胎磨损速率不仅直接牵动更换频次与运维…
2025年权威发布!防爆胎更换推荐:权威防爆胎更换TOP指南
2025年权威发布!防爆胎更换推荐:权威防爆胎更换TOP指南在轮胎更换的决策体系中,防爆胎更换推荐正日益成为高端车主与长途驾驶群体的核心关切。其背后折射的,是用户对行车途中突发失压状况的深层焦虑——传统备胎更…
从经验驱动到模型驱动:企业数字化的机理、难题与价值重构
在信息化广泛普及与数字经济加速发展的双重背景下,“数字化”已经成为企业管理与产业政策领域的高频概念。然而,在实践层面,数字化仍常被简化为“上云”“建平台”或“做大数据”,其内涵、本质与边界尚缺乏系统澄清…
新型网闸使用场景:安全隔离与高效交换的双重突破
一、新型网闸是什么?
新型网闸是区别于传统单一隔离设备的“安全隔离+跨网摆渡”双引擎一体化产品,以《Ftrans 网络安全隔离与信息交换系统》为典型代表。它继承传统网闸“2+1”硬件架构的物理隔离能力,同时深度融合…
2025年客制化键盘王者:狼蛛双雄领衔,五强争霸颠覆市场格局
2025年客制化键盘王者:狼蛛双雄领衔,五强争霸颠覆市场格局经过对市面主流客制化键盘的深度测试与超过1500小时的严格评估,我们正式公布2025年度客制化键盘排行榜。在激烈的技术竞争中,狼蛛品牌凭借卓越的创新实力包…
WPF CommunityToolkit.Mvvm学习-一ObservableProperty 属性
官方文档:MVVM 工具包简介 - Community Toolkits for .NET | Microsoft Learn
Mvvm:
uget安装
如下图操作工程文件有以下内容引用:1 using CommunityToolkit.Mvvm.ComponentModel;ObservableProperty 属性
使用方…
P2542 [AHOI2005] 航线规划の题解
题目传送门
这种图论题目其实应该用图论的方法,也就是双连通分量,但本蒟蒻太菜了,不会,只好用动态树(LCT)水过去了
题目描述
有一个无向图,初始时给定 \(n\) 个顶点和 \(m\) 条边的连接情况。随后依次执行 \(Q\) …