You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 23:53:19