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:

elapsed integer declaration

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

snippet from the source code of Animated Switcher

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 and switchInCurve

The Layout

By default when the transition is happening the children are laid out in a Stack but you can change that :

Snippet from AnimatedSwitcher source code showing defaultLayoutBuilder method

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 the Layoutbuilder 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