-
-
Save Rahkeen/34751655759c200223cd118e6226eadd to your computer and use it in GitHub Desktop.
Swipeable Stack
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@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