I am trying to implement a custom swipe-to-delete card in Jetpack Compose without using any library.
Inside a parent Box, I have two composables layered on top of each other:
The bottom one is a red delete background using matchParentSize()
The top one is a swipable Card
Both composables use the same RoundedCornerShape(8.dp).
However, I see a red outline around the Card, as if the red background is leaking outside the card bounds. I expected the rounded shapes to fully overlap, but the red background is still visible.
What am I missing here? Why does the background appear outside the card even though both use the same shape? This is the code I'm using:
val maxOffset = with(LocalDensity.current) { 80.dp.toPx() }
var offsetX by remember { mutableStateOf(0f) }
Box{
Box(
Modifier.matchParentSize()
.clip(RoundedCornerShape(8.dp))
.background(Color.Red)
.clickable {
Toast.makeText(context,"Clicked the Button",Toast.LENGTH_SHORT).show()
},
contentAlignment = Alignment.CenterEnd
){
IconButton(onClick = {
}) {
Icon(modifier = Modifier.size(30.dp), imageVector = Icons.Default.Delete, contentDescription = null, tint = Color.White)
}
}
Card(
modifier = Modifier
.fillMaxWidth()
.offset { IntOffset(offsetX.roundToInt(), 0) }
.draggable(
orientation = Orientation.Horizontal,
state = rememberDraggableState { delta ->
offsetX = (offsetX + delta)
.coerceIn(-maxOffset, 0f)
},
onDragStopped = {
offsetX = if (offsetX < -maxOffset / 2) {
-maxOffset
} else {
0f
}
}
),
colors = CardDefaults.cardColors(
containerColor = MaterialTheme.colorScheme.onTertiary
),
elevation = CardDefaults.cardElevation(
defaultElevation = 3.dp
),
shape = RoundedCornerShape(8.dp),
) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 5.dp, vertical = 7.dp),
verticalAlignment = Alignment.CenterVertically
){
Image(painter = painter!!,
contentDescription = "",
modifier = Modifier
.size(50.dp)
.clip(RoundedCornerShape(50.dp)),
contentScale = ContentScale.Crop
)
Text(text = username, modifier = Modifier.padding(start = 5.dp))
}
}
}
Here's what it looks like:

