Conditional Progress Indicator in Flutter
⚠ This article covers a previous version of Simple Animation. The basics stay the same but class names have changed.
Last week I introduced AnimationControllerX: an alternative implementation for Flutter’s AnimationController. Today we implement a cool animation with it and look at some advantages.
Let’s take a look at this animation:
When we press the “Load data” button we trigger a HTTP request. To help the user understand what’s happening we present him a custom progress indicator. Here is our animation strategy:
- First it flies in from the top.
- Then it waits for our HTTP request to complete.
- After that it shrinks until it’s not visible anymore.
With regular Flutter animation techniques this can get complex, but for AnimationControllerX this is no problem.
First we create a stateful widget:
We can use the AnimationControllerMixin that inject a ready-to-use instance of AnimationControllerX as controller
into our state class.
In the initState()
method we create a tween for our animation. We use MultiTrackTween that tweens multiple properties at once.
Note: The duration we specify in the MultiTrackTween doesn’t match up with the real animation duration. We only use them to separate the tween into two parts. The first part (1s) will take care of animation controller values from
0.0
to0.5
and the second part (1s) of values from0.5
to1.0
.
The tween is connected to the animation controller by using .animate(controller)
. That means whenever the controller recomputes it current animation value, the tween will update.
Now let’s use the tween to animate our progress indicator:
Our UI consists of two elements: progress indicator and request button. The progress indicator uses the tween.value["TRACK-NAME"]
to apply animated properties to our widgets. Basically it’s a translated and scaled Container widget that has Flutter’s CircularProgressIndicator as it’s child.
We us a boolean _showCircularProgressIndicator
that make sure to only draw the CircularProgressIndicator when it’s actually visible. (CircularProgressIndicator redraws forever and we don’t want unnecessary repaints eating up our device resources.)
Finally we need to implement the logic that triggers the HTTP request, starts the animation and maintains the state of the boolean:
When the user clicks on the “load data” button we trigger our method loadData()
. It starts the HTTP request and sets our variable _dataIsLoaded
to true
when it’s completed.
Then we tell our AnimationControllerX to run some tasks. A FromToTask is the equivalent to regular controllers forward()
and reverse()
functionality. Look how we can easily pass in event listeners. We also can control the speed of a task individually.
The ConditionalTask will wait for a certain condition. In our case we want to wait until our _dataIsLoaded
boolean is true
.
That’s all. We have readable code for animation logic that covers a complex scenario. Achieving that is the goal of my package Simple Animations. You can use in your Flutter apps to create stunning custom animations.
The whole example (including the skipped code for the button widget code) is available here. You can find more examples in the example app.
If you liked it, leave some claps. I appreciate it.
Until next article,
— Felix —