This project provides a customizable flashcard component in Jetpack Compose. The flashcard supports interactive features such as flipping on tap and swiping left or right. The design and functionality of the flashcard component were inspired by the popular Quizlet app. For a real-world usage example, see this component in the full project here.
Uses rotation along the Y-axis to create a flipping effect with cameraDistance
.
- Rotation values range from 0f to 180f to simulate a full flip.
- Alpha blending ensures only one side is visible at a time when the animation is complete.
Swipe animations with rotation on the Z-axis.
- Card Slide Out of View: Cards smoothly slide out of the screen when swiped.
- Border Color Indications: Highlights the card border when approaching a swipe threshold.
Modify text, colors, shapes, and more to match your app's theme.
To use this component in your Jetpack Compose project, simply copy the Flashcard
composable into your project and customize it with your own text and styling.
Here’s an example of how to use the ScratchCard component:
Flashcard(
frontText = "Front of the card",
backText = "Back of the card",
height = 480.dp,
width = 320.dp,
onSwipeLeft = { /* Handle swipe left */ },
onSwipeRight = { /* Handle swipe right */ }
)
The flashcard component is built using a layered rendering approach:
- Flip Animation (Front and Back Sides):
- Rotation (Y-Axis):
- The card rotates around the Y-axis when flipped. Initially, the card shows the front side, and upon flip, it rotates 180°, revealing the back side.
- Alpha Animation (Opacity Transition):
- The front side fades out (opacity 0) as the card rotates.
- Simultaneously, the back side fades in (opacity 1), creating a seamless transition between the two sides.
- Swipe Animation::
- Drag Detection:
- The card’s position (
cardOffsetX
,cardOffsetY
) is updated usingdetectDragGestures
. - The border color changes based on drag direction, and the swipe direction (left or right) is determined by the drag threshold (
SWIPE_GESTURE_THRESHOLD
).
- The card’s position (
- Swipe Completion:
- If the drag exceeds the threshold, the card moves off-screen horizontally by 1.5 times the
screenWidth
and rotates back to 0°. The appropriate callback (onSwipeLeft
oronSwipeRight
) is triggered, and the card resets.
- If the drag exceeds the threshold, the card moves off-screen horizontally by 1.5 times the
- Reset Position:
- After the swipe, the card’s position and border color reset to their initial state.
Parameter | Description | Default |
---|---|---|
modifier |
Modifier applied to the flashcard container. | Modifier |
frontText |
Text displayed on the front side of the card. | Required |
backText |
Text displayed on the back side of the card. | Required |
height |
Height of the flashcard. | 480.dp |
width |
Width of the flashcard. | 320.dp |
borderStrokeWidth |
Width of the border stroke. | 2.dp |
rightSwipeColor |
Color indicating a right swipe. | Green |
leftSwipeColor |
Color indicating a left swipe. | Red |
backgroundColor |
Background color of the flashcard. | Blue |
textColor |
Text color on the flashcard. | Color.White |
shape |
Shape of the flashcard (e.g., rounded corners). | RoundedCornerShape(16.dp) |
topButtonRow |
Optional composable to display buttons at the top of the card. | None |
flipDuration |
Duration of the flip animation in milliseconds. | 400 |
alphaDuration |
Duration of the alpha animation in milliseconds. | 250 |
swipeDuration |
Duration of the swipe animation in milliseconds. | 200 |
swipeThreshold |
Threshold for detecting a swipe gesture. | 70f |
onSwipeLeft |
Callback triggered when the card is swiped to the left. | {} (empty lambda) |
onSwipeRight |
Callback triggered when the card is swiped to the right. | {} (empty lambda) |
onRightSwipeApproach |
Callback triggered when the card is near a right swipe threshold. | {} (empty lambda) |
onLeftSwipeApproach |
Callback triggered when the card is near a left swipe threshold. | {} (empty lambda) |
onNeutralPosition |
Callback triggered when the card is in a neutral (centered) position. | {} (empty lambda) |
Minimum version: Android 7.0 (API level 24) or later📱
Target version: Android 14 (API level 34) or later📱
Adam Dawidziuk🧑💻