I am required to create a UI in Jetpack Compose of a card that initially takes some constant height but the user can drag on it to increase or decrease its height and show more or less content. It's very similar to a Bottom Sheet in its behavior but I don't want my UI to be anchored to the bottom of the screen like how a Bottom Sheet is.
Here's how my card looks now:
Can you tell me how can I do this? I need to increase and decrease the height with user similar to what you have in a Bottom Sheet.
I managed to do it using Compose-Foundation AnchoredDraggable
like below:
Things taken into consideration while implementing this:
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun ExpandableColumn(
modifier: Modifier = Modifier,
content: @Composable ColumnScope.() -> Unit
) {
val density = LocalDensity.current
// TODO replace these fixed values with calculated values depending on content
val collapsedHeight = 300.dp
val expandedHeight = 600.dp
val state = remember {
AnchoredDraggableState<CardDragAnchors>(
initialValue = CardDragAnchors.Collapsed,
positionalThreshold = { distance: Float -> distance * 0.5f },
velocityThreshold = { with(density) { 100.dp.toPx() } },
animationSpec = tween(),
).apply {
updateAnchors(
DraggableAnchors {
CardDragAnchors.Collapsed at with(density) { collapsedHeight.toPx() }
CardDragAnchors.Expanded at with(density) { expandedHeight.toPx() }
}
)
}
}
Column(
modifier = Modifier
.fillMaxWidth()
.height(with(density) { state.offset.toDp() })
.anchoredDraggable(
state = state,
orientation = Orientation.Vertical,
enabled = true,
reverseDirection = true,
)
.then(modifier)
) {
content()
}
}
private sealed interface CardDragAnchors {
data object Collapsed : CardDragAnchors
data object Expanded : CardDragAnchors
}