Magically animate Widgets with ease
Animated Switcher is one of the least known widgets in Flutter. The first time I heard about this widget was in a group meeting with Simon Lightfoot(The Flutter Whisperer). It was brought up in conversation and from that moment, I was couldn’t stop using it.
In this article, I am going to pass on what I have learnt and show some cool examples of AnimatedSwitcher
.
When can this widget be used
- When removing/inserting a widget from the tree.
- When switching between widgets.
- When values changes
Minimal example
Let’s start by a very simple example where we will hide/show a widget when the user clicks the FAB
NOTE: Always use a
SizedBox
to represent something invisible or a NULL widget because we can’t just return NULL in the Build method
As you can see, when the FAB is pressed, the widgets fades in and out. This is a really simple example of how AnimatedSwitcher
works. For something a bit more complex, let’s try to switch do this but between two widgets with the same type!
If we replace SizedBox
with Container
, there will be no visible change. This is because Flutter compares widgets widget’s using canUpdate
. It checks the runtimeType as well as the key of widgets to determine if there is a change.
What this means is if you need to switch between two widget of the same type, a key must be supplied to the widgets. Keys are used to identify widgets in Flutters widgets hierarchy. We can use any local key but to keep things simple, I will use UniqueKey
.
Let’s modify our previous example so that it looks like the snippet below:
At first glance you might be saying this the same as AnimatedCrossFade
but more complicated. You’re not wrong to think this but we’ve only barely touched the surface of AniamtedSwitcher
. In the next section, we will take a deeper look at AnimatedSwitcher
.
Switch between Values
Building on what we’ve learnt in the previous section, we are now going to switch between widgets when their values change. A good example of this would be the countdown where the Text widget displays the elapsed time. When a new value is omitted from the countdown, AnimatedSwitcher
will run the transition Effect:
Create a simple Count Down
I will aCountdownTimer
using the quiver.async
library:
We will then declare the elapsed integer in the state of the widget:
finally, change the child of the AniamtedSwitcher
to a Text
widget :
Very simple right?
The only thing that’s new in our above code would be the use of ValueKey
. Value Key is another type of local key which gives your widget a unique id for every value.
The final result looks cool but we can make it even cooler by making our own custom transition:
Custom Transition
The AnimatedSwitcher
uses a FadeTransiton
by default
Using the transitionBuilder
property we can make custom transitions. Let’s reuse our count down example and modify it with a ScaleTransition
:
At this point you can feel free to play, change and create your own transitions.
A common problem you might run into occurs when using Animation<double>. Let's say you have a SlideTransiton
and your animation is Animation<double>
. You might be wondering how to use this animation Well the answer is really easy just create a new animation driven by this animation.
Here is an example:
One trick that may make this example even better is clipping! Let us wrap the SlideTransition
with a ClipRect
. This will prevent us from seeing two widgets at the same time.
Additional info: You can customize the in/out curves as well using
switchOutCurve
andswitchInCurve
The Layout
By default when the transition is happening the children are laid out in a Stack
but you can change that :
The layout here is simple but let’s make something more advanced:
The first thing of note in the above GIF is we have only one widget which is the current widget. We can get this by changing the layout :
The second thing is the animation has a small delay when the widget is in Clipped Area. This is because I used a TweenSequence
rather than a simple Tween animation:
NOTE :
ConstantTween
is a tween with a constant value. I used it to stop the sequence for a small amount of time.
The final piece of our puzzle is ClipRect
. It is used just to show a fixed part in the transition. Without it, you will see the full transition from 1.0 to -1.0
NOTE : You can use the
ClipRect
in theLayoutbuilder
but clipping is expensive and the layoutBuilder is called every time this widget is built and the transionBuilder is only called when a new child is set
Use different in/out animation
By default the AniamtedSwitcher
will just reverse the in animation to get the out animation. This is okay for most cases but it would be cool if we can customize that as well. Unfortunately, this is not something provided by the public API. There is an open issue for that, however, for now, I will just use this method.
The idea is all about keys. We will compare the child key with the current ValueKey
and decide what to do after that
Here is the final result for this example
For more articles don’t forget to follow me and Flutter Community on medium and Twitter.
Check out some of my other articles: https://medium.com/@rahiche