I would like to create a calendar date card in Jetpack Compose that closely matches this design, maintaining the same wave patterns and path shapes. My goal is to ensure that the visual elements, such as the curves and overall layout.
Thank you so much for your help
You can achieve it by using below code block
package com.example.demo
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Outline
import androidx.compose.ui.graphics.Path
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.graphics.drawscope.Stroke
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
@Preview
@Composable
fun WaveCardWithOutline() {
Box(
modifier = Modifier
.size(100.dp)
) {
Column(
modifier = Modifier
.fillMaxWidth()
.height(94.dp)
.clip(RoundedCornerShape(topStart = 8.dp, topEnd = 8.dp))
.clip(waveShape())
.background(Color.Red),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
Text(
text = "20",
fontSize = 32.sp,
fontWeight = FontWeight.Bold,
color = Color.White
)
Text(
text = "Dec",
fontSize = 24.sp,
fontWeight = FontWeight.Medium,
color = Color.White
)
}
Canvas(
modifier = Modifier
.matchParentSize()
) {
val path = createBottomOutlinePath(size)
drawPath(path, color = Color.Red, style = Stroke(width = 2.dp.toPx()))
}
}
}
fun waveShape(): Shape = object : Shape {
override fun createOutline(size: Size, layoutDirection: LayoutDirection, density: Density): Outline {
val path = createWavePath(size)
return Outline.Generic(path)
}
}
fun createWavePath(size: Size): Path {
return Path().apply {
moveTo(0f, 0f)
lineTo(0f, size.height - 10f)
val waveHeight = 10f
val waveWidth = size.width / 5
for (i in 0 until 5) {
val x1 = (i * waveWidth) + (waveWidth / 2)
val y1 = if (i % 2 == 0) size.height - (waveHeight * 2) else size.height
val x2 = (i + 1) * waveWidth
val y2 = size.height - 10f
quadraticBezierTo(x1, y1, x2, y2)
}
lineTo(size.width, 0f)
close()
}
}
fun createBottomOutlinePath(size: Size): Path {
return Path().apply {
val waveHeight = 10f
val waveWidth = size.width / 5
moveTo(0f, size.height - 10f)
for (i in 0 until 5) {
val x1 = (i * waveWidth) + (waveWidth / 2)
val y1 = if (i % 2 == 0) size.height - (waveHeight * 2) else size.height
val x2 = (i + 1) * waveWidth
val y2 = size.height - 10f
quadraticBezierTo(x1, y1, x2, y2)
}
}
}