I am trying to create a border at the bottom of a card using jetpack compose.
Kind of like this in order to make the card feel like it has a thickness to it.
I did manage to get that working using two cards "stacked" on top of eachother
Box(modifier = Modifier
.wrapContentSize()
.padding(5.dp)
.padding(25.dp)
.padding(0.dp,0.dp,0.dp,15.dp)) {
Card(
modifier = Modifier
.size(180.dp, 200.dp)
.offset(10.dp, 12.dp),
elevation = CardDefaults.cardElevation(
defaultElevation = 10.dp
)
) {
}
Card(
modifier = Modifier
.size(180.dp, 200.dp)
.offset(10.dp, 10.dp),
elevation = CardDefaults.cardElevation(
defaultElevation = 10.dp
)
) {
}
}
But to me this feels like a pretty hacky solution and something I would like to avoid. So I wonder if there is any other ways of creating a similar effect?
You could try and experiment with drawBehind
modifier. Stacking of rounded rects is involved too, but it looks much cleaner to me.
Snippet below produces the following result:
When you uncomment the line with semi-transparent backgroundColor
, you can see what is being drawn behind the Card (it is full rounded rect, as you cannot set corners individually on Canvas with this method):
@Preview
@Composable
fun CardWithThickness(modifier: Modifier = Modifier) {
val cardHeightDp = 100.dp
val cornerRadiusDp = 20.dp
val borderThicknessDp = 2.dp
Box(
modifier = Modifier.padding(bottom = borderThicknessDp)
) {
Card(
// backgroundColor = Color(0x99999999),
shape = RoundedCornerShape(size = cornerRadiusDp),
modifier = Modifier
.size(180.dp, cardHeightDp)
.drawBehind {
drawRoundRect(
color = Color.Red,
topLeft = Offset(0f, (cardHeightDp - 2 * cornerRadiusDp).toPx()),
size = this.size.copy(height = (2 * cornerRadiusDp + borderThicknessDp).toPx()),
cornerRadius = CornerRadius(cornerRadiusDp.toPx())
)
},
) {
// ...
}
}
}