Creating a Countdown Timer using Animation in Flutter
In this article, I will be building a count down timer with the help of the animation and using custom paint.
First of all, create an app which returns the MaterialApp.
Now create a new Widget CountDownTimer
and make sure that it must be a Stateful Widget because we are using animation
and we will need to add TickerProviderStateMixen
.
class CountDownTimer extends StatefulWidget {
@override
_CountDownTimerState createState() => _CountDownTimerState();
}
class _CountDownTimerState extends State<CountDownTimer>
with TickerProviderStateMixin {
}
Create an Animation Controller
Create an animation controller and initialise it in initState()
.
AnimationController controller;
@override
void initState() {
super.initState();
controller = AnimationController(
vsync: this,
duration: Duration(seconds: 5),
);
}
I am right now using only 5-second duration for my animation to happen.
Create a Circular progress bar using Custom paint
Create a class which extends CustomPainter
class CustomTimerPainter extends CustomPainter
Add properties
Now we will need some properties so we can customize my custom painter class from my widgets screen.
class CustomTimerPainter extends CustomPainter {
CustomTimerPainter({
this.animation,
this.backgroundColor,
this.color,
}) : super(repaint: animation);
final Animation<double> animation;
final Color backgroundColor, color;
}
I am using background color and color property for my Circular progress bar and to animate my progress bar, I will need an animation.
Override methods
We will override our paint method which will use to paint our circular progress bar.
First, we will paint a circle and we will create an arc will move around the circle.
In the paint method, create a Paint
object and add properties.
Paint paint = Paint()
..color = backgroundColor
..strokeWidth = 10.0
..strokeCap = StrokeCap.butt
..style = PaintingStyle.stroke;
Now draw a circle
canvas.drawCircle(size.center(Offset.zero), size.width / 2.0, paint);
When the circle is painted then will need to draw an arc to move.
paint.color = color;
double progress = (1.0 - animation.value) * 2 * math.pi;
canvas.drawArc(Offset.zero & size, math.pi * 1.5, -progress, false, paint);
Change the color of the paint and update the process using the current animation value and draw the arc.
Now we also have an override method shouldRepaint
.
@override
bool shouldRepaint(CustomTimerPainter old) {
return animation.value != old.animation.value ||
color != old.color ||
backgroundColor != old.backgroundColor;
}
Here is the code for the CustomTimerPainter
class
https://gist.github.com/flutter-devs/cc42bd1506770b35025b59afd493e203#file-customtimerpainter-dart
Create the UI
To animate my Custom Progress bar we will wrap my an AnimatedBuilder
and provide the animation and it returns a CustomPaint
Widget. When My animation will start the value of the arc will update in the custom painter class and update the UI
AnimatedBuilder(
animation: controller,
builder:
(BuildContext context, Widget child) {
return CustomPaint(
painter: CustomTimerPainter(
animation: controller,
backgroundColor: Colors.white,
color: themeData.indicatorColor,
));
},
),
And to start and pause the animation Ill use the Floating Action Button, we have also Wrapped my FAB with AnimatedBuilder
so we can update my play and pause status.
AnimatedBuilder(
animation: controller,
builder: (context, child) {
return FloatingActionButton.extended(
onPressed: () {
if (controller.isAnimating)
controller.stop();
else {
controller.reverse(
from: controller.value == 0.0
? 1.0
: controller.value);
}
},
icon: Icon(controller.isAnimating
? Icons.pause
: Icons.play_arrow),
label: Text(
controller.isAnimating ? "Pause" : "Play"));
}),
Now if we see the app, it will look like this
Now Wrap the CustomTimerPainter
inside the Stack and add text to represent the value.
https://gist.github.com/flutter-devs/8b8a56051de58b44f0997270d76aa037#file-countdowntimer-dart
To convert the animation duration into time String.
String get timerString {
Duration duration = controller.duration * controller.value;
return '${duration.inMinutes}:${(duration.inSeconds % 60).toString().padLeft(2, '0')}';
}
Here is the code of CountDownTimer Widget
https://gist.github.com/flutter-devs/fb872f913be7aaddab061493b3988c59#file-countdowntimer-dart
I have wrapped the root body widget and added a new Container and animating with animation value.
Container(
color: Colors.amber,
height:
controller.value * MediaQuery.of(context).size.height,
),
Here this complete code
flutter-devs/CountDownTimer
Contribute to flutter-devs/CountDownTimer development by creating an account on GitHub.github.com
Thanks for reading this article ❤
If I got something wrong, Let me know in the comments. I would love to improve.
Clap 👏 If this article helps you.
Connect with me on Linkedin and Github
Feel free to connect with us:
And read more articles from FlutterDevs.com.
FlutterDevs team of Flutter developers to build high-quality and functionally-rich apps. Hire a flutter developer for your cross-platform Flutter mobile app project on an hourly or full-time basis as per your requirement! You can connect with us on Facebook, GitHub, Twitter, and LinkedIn for any flutter-related queries.
We welcome feedback and hope that you share what you’re working on using #FlutterDevs. We truly enjoy seeing how you use Flutter to build beautiful, interactive web experiences.