Skip to content

Instantly share code, notes, and snippets.

@tejaswini-dev-techie
Created November 15, 2024 10:05
Show Gist options
  • Select an option

  • Save tejaswini-dev-techie/2b686ea47a72f60d509b8722750ce1bc to your computer and use it in GitHub Desktop.

Select an option

Save tejaswini-dev-techie/2b686ea47a72f60d509b8722750ce1bc to your computer and use it in GitHub Desktop.
Flutter animated timer that counts up smoothly with dynamic transitions
import 'package:flutter/material.dart';
import 'dart:async';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'CountUp Timer Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const TimerScreen(),
);
}
}
class TimerScreen extends StatelessWidget {
const TimerScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color(0xFFffedb7),
appBar: AppBar(
title: const Text("CountUp Timer"),
),
body: Center(
child: CountUpTimer(
maxDuration: const Duration(seconds: 10), // Set the duration
),
),
);
}
}
class CountUpTimer extends StatefulWidget {
final Duration maxDuration;
const CountUpTimer({Key? key, this.maxDuration = const Duration(minutes: 15)}) : super(key: key);
@override
_CountUpTimerState createState() => _CountUpTimerState();
}
class _CountUpTimerState extends State<CountUpTimer> {
Duration duration = const Duration(); // Starts from 0
Timer? timer;
@override
void initState() {
super.initState();
startTimer();
}
void startTimer() {
timer = Timer.periodic(const Duration(seconds: 1), (_) => addTime());
}
void addTime() {
setState(() {
final seconds = duration.inSeconds + 1;
if (seconds >= widget.maxDuration.inSeconds + 1) {
timer?.cancel();
} else {
duration = Duration(seconds: seconds);
}
});
}
@override
void dispose() {
timer?.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
return buildTime();
}
Widget buildTime() {
String twoDigits(int n) => n.toString().padLeft(2, '0');
final hours = twoDigits(duration.inHours);
final minutes = twoDigits(duration.inMinutes.remainder(60));
final seconds = twoDigits(duration.inSeconds.remainder(60));
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
buildTimeColumn(hours, "Hrs"),
buildTimeColumn(minutes, "Mins"),
buildTimeColumn(seconds, "Secs", isLast: true),
],
);
}
Widget buildTimeColumn(String time, String label, {bool isLast = false}) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Row(
children: [
buildDigit(time[0]),
buildDigit(time[1]),
if (!isLast) buildTimeSeparator(),
],
),
buildLabel(label),
],
);
}
Widget buildDigit(String digit) {
return Container(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 4),
margin: const EdgeInsets.symmetric(horizontal: 2),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
),
child: ClipRect(
child: AnimatedSwitcher(
duration: const Duration(milliseconds: 600),
switchInCurve: Curves.easeOutExpo,
switchOutCurve: Curves.easeInExpo,
transitionBuilder: (Widget child, Animation<double> animation) {
return Stack(
children: <Widget>[
SlideTransition(
position: Tween<Offset>(
begin: const Offset(0, -1),
end: const Offset(0, 1),
).animate(CurvedAnimation(
parent: animation,
curve: Curves.easeOutCubic,
)),
child: FadeTransition(
opacity: animation,
child: child,
),
),
SlideTransition(
position: Tween<Offset>(
begin: const Offset(0, -1),
end: const Offset(0, 0),
).animate(CurvedAnimation(
parent: animation,
curve: Curves.bounceIn,
)),
child: FadeTransition(
opacity: animation,
child: child,
),
),
],
);
},
child: Text(
digit,
key: ValueKey<String>(digit),
style: const TextStyle(
fontWeight: FontWeight.bold,
color: Colors.black,
fontSize: 50,
),
),
),
),
);
}
Widget buildLabel(String label) {
return Text(
label,
style: const TextStyle(
color: Colors.black,
fontSize: 20,
fontWeight: FontWeight.bold,
),
);
}
Widget buildTimeSeparator() {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 2.0),
child: const Text(
":",
style: TextStyle(
color: Colors.black,
fontSize: 50,
),
),
);
}
}
@tejaswini-dev-techie
Copy link
Author

tejaswini-dev-techie commented Nov 15, 2024

πŸŽ‰ Check out the Animated Count-Up Timer! ⏱️

Experience a sleek, animated timer that counts up smoothly with dynamic transitions. Perfect for keeping track of time in your app with an engaging and modern UI! πŸ”₯

Whether you're building a fitness tracker, a countdown, or just want a stylish timer, this animated CountUp Timer will elevate your app's design and functionality!

Try it now and add a professional touch to your project. πŸš€

βœ… For Countdown Timer: Learn how to build a countdown timer with animations to add excitement to your time-sensitive features.
πŸ‘‰ Read the step-by-step guide on Medium

Visual Preview

animated_count_up_timer_preview.mov

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment