Flutter Progress Bar Button
Flutter is in my opinion one of the most interesting frameworks to learn if you don’t have any previous experience developing Mobile Apps, throughout this post you will learn how easy is to create reusable components a.k.a Widgets “in Flutter jargon”.
Let’s start!
Create a new application using flutter command line cli
Assuming you already have installed flutter in your computer (if not read this first) run this from console / powershell :
flutter create progress_button
After finishing, open the application in your favorite IDE — with Flutter support — in my case Visual Studio Code, as you know you will encounter the starter application provided by Flutter by default, We will clean up a little bit all the extra comments and the code that We will not to use, the ending result must be like this :
Try to run on Emulator or device and it will look like this:
Create a Folder and name it widgets (or whatever you want) and inside this create another one and name it animated_ui *this step is optional is only needed as order*.
Creating the Progress Bar Button Widget
Inside widgets/animated_ui create a new file: animated_pgbutton.dart the name of course is up to you.
From here We will perform the following steps:
- Create a StatefulWidget, to hold the state of our button
- Create an AnimationController to manage our animations
- Create two Animations one for size and one for color
- And Finally using a Stack We will create the UI
Inside the animated_pbbutton.dart place the following code:
from line 3 to 16 is the creation of the StatefulWidget who is in charge to hold and mutate the state, of course at this stage maybe is not clear how it works or why is need it but hold on it will use it in a moment.
If you want to learn a little more about the concepts of Widgets, Stateful and Stateless or is not completely clear check the flutter documentation about Widgets here: https://flutter.dev/docs/development/ui/widgets-intro
Now from line 18 to 41 is the UI construction and we will stop a moment to explain what is happen here, We are using the Stack Widget and as its name suggests this allow us to place a Widget in front others Widgets, the idea is place a Container below and on it our Button and manipulating the size and color to our container simulate a progress bar, observing the code we can deduct that the first element in the Child Array for the Stack Widget is the belowest one. To achieve the progress bar we Set the top margin of the container the same as our button height and the container height to 5.
Is valid and important to clarify that this is only one possible approach, one of many others could be use a Column Widget instead a Stack.
After the creation of our Widget We need to modify the main.dart, import the file and place the AnimatedProgressButton class in the body of our Scaffold Widget, do a full restart and run on Emulator / Device and should look like this:
At this point if you tap the button almost nothing happen, is time to add the Animations to our Widget.
Animations core concepts
As we mention before we gonna use two animations one for the size and one for the color, Animation Class is a Generic Class that interpolates the values used to guide our Animation, Generic implies that allow us to interpolate various types e.g. double and Color to name a few, interpolate implies that animation object will give us a values between the limits defined by Tweens, but for all the work of the Animations works is needed to associate them to a controller or orchestrator than handles the Animation and this is responsibility to AnimationController, ok enough blah, blah, let’s code again, to clarify this concepts.
Analyze this code by your own before incorporate to our Widget.
And now join everything
Before show the result I will explain some parts of the code:
At line 23: The initialization of AnimationController required two params the first one for duration and then vsync, yeah but what vsync is ? vsync represent a TicketProvider that is who one in charge to register itself with the SchedulerBinding and fires a callback every frame that is the way controls the Animation, then, if we pass this to vsync, means every StatefulWidget is a TicketProvider? no, but, we can use TicktProvider in every widget using:
At line 10: SingleTickerProviderStateMixin, give us the ability to register in the ShedulerBinding and synchronice our widget with the frames. SingleTickerProvider is used for efficiency because we only have one AnimationController.
At line 28: We initialize the _animatedSize used to manipulate the size, using Tween<double> to match the type in the declaration at line 13. The Animation Class exposes two Listeners
- addListener: Executed every time the value of Animation change, generally used to update our interface.
- addStatusListener: Executed every time the status of our Animation change between some of the following values [completed, dismissed, forward, reverse]. In our example we control the status to create a Loop in line 34.
At line 36: We initialize the _animatedColor using ColorTween a subclass of Tween than interpolate between the two provided colors.
At line 50: Method fired by our button to start the animation and after 2 seconds (Controller by timer) stops and reset the Animation to its original state.
Finally, in lines 67 and 68 we use our animations and to get the generated values we use the value property.
And the Final Result must be something like this:
Conclusion
Flutter is one of the most flexible frameworks to build Mobile Applications, and as you can see allow us to create Animation and Widgets that can be easily reused along all our projects.
Resources
Sources
You can find the code for this here
Any Question or comment is welcome, and if you find any mistake on the code please don’t hesitate to share is the best way to learn.
Thanks and Happy Fluttery !