Skip to content

Instantly share code, notes, and snippets.

@Rahkeen
Created December 2, 2023 21:47
Show Gist options
  • Save Rahkeen/34751655759c200223cd118e6226eadd to your computer and use it in GitHub Desktop.
Save Rahkeen/34751655759c200223cd118e6226eadd to your computer and use it in GitHub Desktop.
Swipeable Stack
@Preview
@Composable
fun SwipeableStack() {
var state by remember {
mutableStateOf(
listOf(
CoolRed,
CoolYellow,
CoolGreen,
CoolBlue,
CoolPurple
)
)
}
Box(
modifier = Modifier.fillMaxSize().background(color = Granite),
contentAlignment = Alignment.Center
) {
state.forEachIndexed { index, color ->
key(color) {
val reversed = state.lastIndex - index
val offset = reversed * -30f
val scale = 1f - reversed / 30f
SwipeableCard(color = color, offset = offset, scale = scale) {
state = listOf(color) + (state - color)
}
}
}
}
}
@Composable
fun SwipeableCard(
color: Color,
offset: Float,
scale: Float,
action: () -> Unit
) {
var dragging by remember {
mutableStateOf(false)
}
var dragOffset by remember { mutableStateOf(Offset.Zero) }
val animatedOffset by animateOffsetAsState(
targetValue = when {
dragging -> Offset(0f, offset) + dragOffset
else -> Offset(0f, offset)
},
animationSpec = if (dragging) snap() else spring(
dampingRatio = Spring.DampingRatioMediumBouncy,
stiffness = Spring.StiffnessLow
),
label = ""
)
val animatedScale by animateFloatAsState(
targetValue = scale,
label = "card scale"
)
Box(
modifier = Modifier
.offset { animatedOffset.round() }
.scale(scale = animatedScale)
.width(200.dp)
.height(300.dp)
.clip(RoundedCornerShape(16.dp))
.background(color = color)
.pointerInput(Unit) {
detectDragGestures(
onDragStart = {
dragOffset = Offset.Zero
dragging = true
},
onDragEnd = {
dragging = false
// potentially check if we should reorder the list
action()
},
onDrag = { change, dragAmount ->
change.consume()
dragOffset += dragAmount
}
)
}
)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment