Compose Timer - Android Dev Challenge

Kotlin GitHub

Android Dev Challenge Week 2

After successfully completing the first week’s pet adoption challenge, I was eager to tackle Week 2: build a countdown timer app. This time, the focus was on animations - a perfect opportunity to explore Compose’s animation capabilities.

Design Inspiration

The UI was inspired by Playsharp’s Countdown design on Dribbble - a clean, modern timer with satisfying visual feedback.

Timer Initial State
Timer Initial State
Timer Running
Timer Running

Technical Highlights

Canvas Drawing

The circular progress indicator is drawn directly on a Canvas, giving full control over the animation:

@Composable
fun TimerCircle(progress: Float, modifier: Modifier = Modifier) {
Canvas(modifier = modifier.size(200.dp)) {
// Background circle
drawArc(
color = Color.Gray.copy(alpha = 0.3f),
startAngle = -90f,
sweepAngle = 360f,
useCenter = false,
style = Stroke(width = 12.dp.toPx(), cap = StrokeCap.Round)
)
// Progress arc
drawArc(
color = Color.Blue,
startAngle = -90f,
sweepAngle = 360f * progress,
useCenter = false,
style = Stroke(width = 12.dp.toPx(), cap = StrokeCap.Round)
)
}
}

Text Animations

The countdown numbers animate smoothly with scale and fade effects:

@Composable
fun AnimatedNumber(number: Int) {
val scale by animateFloatAsState(
targetValue = 1f,
animationSpec = spring(
dampingRatio = Spring.DampingRatioMediumBouncy,
stiffness = Spring.StiffnessLow
)
)
Text(
text = number.toString(),
modifier = Modifier.scale(scale),
style = MaterialTheme.typography.h1
)
}

Lottie Integration

For celebratory moments (like timer completion), Lottie animations add that extra polish:

@Composable
fun CompletionAnimation() {
val composition by rememberLottieComposition(
LottieCompositionSpec.RawRes(R.raw.confetti)
)
val progress by animateLottieCompositionAsState(composition)
LottieAnimation(
composition = composition,
progress = { progress }
)
}

Compose Animation Learnings

This project deepened my understanding of Compose animations:

  1. animateFloatAsState - Simple value animations
  2. updateTransition - Coordinated animations for state changes
  3. Canvas - Custom drawing with full control
  4. Lottie - Complex animations from After Effects

Animation Specs

// Spring animation for bouncy effects
spring(dampingRatio = 0.5f, stiffness = 300f)
// Tween for predictable timing
tween(durationMillis = 500, easing = FastOutSlowInEasing)
// Keyframes for complex sequences
keyframes {
durationMillis = 1000
0f at 0
0.5f at 500
1f at 1000
}

What I Learned

  1. Canvas is powerful - For custom graphics, nothing beats direct Canvas drawing
  2. Animation composition - Compose makes it easy to layer multiple animations
  3. State-driven animations - Animations react to state changes naturally
  4. Lottie integration - Easy to add professional animations with the Lottie library

Resources