如何在Jetpack Compose中创建带波浪效果的日历日期卡片
Jetpack Compose 实现匹配设计的日历日期卡片
要实现和参考设计一致的日历卡片,核心是通过Canvas绘制自定义波浪路径背景,再叠加日期文本布局。以下是完整实现方案:
1. 自定义波浪背景卡片实现
通过Path构建带顶部圆角和底部波浪的卡片形状,结合Canvas绘制背景,再在上方布局日期相关文本:
@Composable fun CalendarDateCard( day: String, weekDay: String, month: String, modifier: Modifier = Modifier ) { // 卡片基础尺寸配置,可根据设计调整 val cardWidth = 80.dp val cardHeight = 100.dp val cornerRadius = 12.dp val waveHeight = 12.dp val density = LocalDensity.current // 转换为像素值用于路径计算 val cardWidthPx = with(density) { cardWidth.toPx() } val cardHeightPx = with(density) { cardHeight.toPx() } val cornerRadiusPx = with(density) { cornerRadius.toPx() } val waveHeightPx = with(density) { waveHeight.toPx() } Box(modifier = modifier.size(cardWidth, cardHeight)) { // 绘制波浪背景 Canvas(modifier = Modifier.fillMaxSize()) { val path = Path().apply { // 左上角圆角 moveTo(cornerRadiusPx, 0f) arcTo( rect = Rect(0f, 0f, cornerRadiusPx * 2, cornerRadiusPx * 2), startAngleDegrees = 180f, sweepAngleDegrees = 90f, forceMoveTo = false ) // 顶部直线到右上角 lineTo(cardWidthPx - cornerRadiusPx, 0f) // 右上角圆角 arcTo( rect = Rect(cardWidthPx - cornerRadiusPx * 2, 0f, cardWidthPx, cornerRadiusPx * 2), startAngleDegrees = 270f, sweepAngleDegrees = 90f, forceMoveTo = false ) // 右侧直线到波浪起始点 lineTo(cardWidthPx, cardHeightPx - waveHeightPx) // 第一个波浪曲线(向下凹) quadraticBezierTo( x1 = cardWidthPx * 0.75f, y1 = cardHeightPx - waveHeightPx * 1.5f, x2 = cardWidthPx * 0.5f, y2 = cardHeightPx - waveHeightPx ) // 第二个波浪曲线(向上凸) quadraticBezierTo( x1 = cardWidthPx * 0.25f, y1 = cardHeightPx - waveHeightPx * 0.5f, x2 = 0f, y2 = cardHeightPx - waveHeightPx ) // 左侧直线回到起点,闭合路径 lineTo(0f, cornerRadiusPx) close() } // 绘制背景色,可替换为设计中的颜色 drawPath(path = path, color = Color(0xFFF5F5F5)) } // 日期文本布局 Column( modifier = Modifier.fillMaxSize(), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center ) { Text( text = day, fontSize = 32.sp, fontWeight = FontWeight.Bold, color = Color(0xFF333333) ) Spacer(modifier = Modifier.height(4.dp)) Text( text = weekDay, fontSize = 12.sp, color = Color(0xFF666666) ) Spacer(modifier = Modifier.height(4.dp)) Text( text = month, fontSize = 10.sp, color = Color(0xFF999999) ) } } }
2. 使用示例
在界面中直接调用该Composable即可:
@Composable fun DemoScreen() { Column( modifier = Modifier.fillMaxSize().padding(16.dp), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center ) { CalendarDateCard(day = "25", weekDay = "星期四", month = "六月") } }
3. 调整匹配设计细节
- 如果需要更贴合设计的波浪弧度,可修改
quadraticBezierTo的控制点坐标(x1、y1) - 卡片尺寸、圆角大小、颜色值可根据参考设计直接替换
- 文本的字体、大小、间距也可根据设计调整参数
内容的提问来源于stack exchange,提问作者rlaj
相关产品推荐
相关产品推荐

