Flutter - Using AnimatedCrossFade Widget Examples

This tutorial shows you how to use AnimatedCrossFade widget in Flutter.

If you need to have fade transition effects between two widgets in Flutter, there's a widget that's suitable for that purpose. With AnimatedCrossFade, you can easily create fading effects when a widget is being replaced with another. It supports any kind of Flutter's Widget such as Image, Text, Icon and anything that extends Widget. In addition, it allows you to customize the animation including how long it will be played and the animation curves to be used. How to create an AnimatedCrossFade and how to apply customization to it are going to be explained in this tutorial.

Creating AnimatedCrossFade

The constructor of AnimatedCrossFade has a lot of parameters. Some of them are required. You have to pass firstChild (Widget), secondChild (Widget), crossFadeState (CrossFadeState), and duration (Duration). firstChild and secondChild are the widgets to be shown. firstChild will be shown if the value of crossFadeState is CrossFadeState.showFirst. If crossFadeState is set to CrossFadeState.showSecond, secondChild will be shown. How long the animation duration from the first to second child depends on duration value. The list of available properties can be seen on properties section.

Below is a basic example of using AnimatedCrossFade widget.

  AnimatedCrossFade(
    crossFadeState: _crossFadeState,
    duration: const Duration(seconds: 2),
    firstChild: const Icon(Icons.text_rotate_up, size: 150),
    secondChild: const Icon(Icons.text_rotate_vertical, size: 150),
  ),

Output:

Flutter - AnimatedCrossFade - basic

 

Setting Animation Curve

The default animation curve is Curves.linear. It can be replaced by using firstCurve value for the animation from firstChild to secondChild.

  AnimatedCrossFade(
    crossFadeState: _crossFadeState,
    duration: const Duration(seconds: 2),
    firstCurve: Curves.bounceInOut,
    secondCurve: Curves.easeInBack,
    firstChild: const Icon(Icons.text_rotate_up, size: 150),
    secondChild: const Icon(Icons.text_rotate_vertical, size: 150),
  ),

Output:

Flutter - AnimatedCrossFade - curve

 

Setting Reverse Animation

If you need to also have a reverse animation or in other word animation from secondChild to firstChild, you can set a different duration using reverseDuration property. For setting the curve, use secondCurve property.

  AnimatedCrossFade(
    crossFadeState: _crossFadeState,
    duration: const Duration(seconds: 2),
    reverseDuration: const Duration(seconds: 1),
    firstCurve: Curves.bounceInOut,
    firstChild: const Icon(Icons.text_rotate_up, size: 150),
    secondChild: const Icon(Icons.text_rotate_vertical, size: 150),
  )

Output:

Flutter - AnimatedCrossFade - reverse

 

Using Custom layoutBuilder

You can use a custom layout builder for positioning the widget during the transition. What you need to do is creating an AnimatedCrossFadeBuilder.

  AnimatedCrossFadeBuilder = Widget Function(Widget topChild, Key topChildKey, Widget bottomChild, Key bottomChildKey)

Then pass it as layoutBuilder. The returned widget is wrapped in an AnimatedSize widget. The below example returns a Stack Widget with the firstChild placed on a customized position.

  AnimatedCrossFade(
    crossFadeState: _crossFadeState,
    duration: const Duration(seconds: 2),
    firstChild: const Icon(Icons.text_rotate_up, size: 100),
    secondChild: const Icon(Icons.text_rotate_vertical, size: 200),
    layoutBuilder: (Widget topChild, Key topChildKey, Widget bottomChild, Key bottomChildKey) {
      return Stack(
        clipBehavior: Clip.none,
        children: <Widget>[
          Positioned(
            key: bottomChildKey,
            left: 100.0,
            top: 100.0,
            child: bottomChild,
          ),
          Positioned(
            key: topChildKey,
            child: topChild,
          ),
        ],
      );
    },
  ),

Output:

Flutter - AnimatedCrossFade - layoutBuilder

 

Full code

Below is a full code example with reverse animation, custom curves, and custom layout builder.

  import 'package:flutter/material.dart';
  
  void main() => runApp(MyApp());
  
  class MyApp extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
      return MaterialApp(
        title: 'Woolha.com Flutter Tutorial',
        home: _AnimatedCrossFadeExample(),
      );
    }
  }
  
  class _AnimatedCrossFadeExample extends StatefulWidget {
    @override
    _AnimatedCrossFadeExampleState createState() =>
        new _AnimatedCrossFadeExampleState();
  }
  
  class _AnimatedCrossFadeExampleState extends State<_AnimatedCrossFadeExample> {
    CrossFadeState _crossFadeState = CrossFadeState.showFirst;
  
    @override
    void initState() {
      super.initState();
  
      Future.delayed(const Duration(seconds: 3), () {
        setState(() {
          _crossFadeState = CrossFadeState.showSecond;
        });
      });
  
      Future.delayed(const Duration(seconds: 5), () {
        setState(() {
          _crossFadeState = CrossFadeState.showFirst;
        });
      });
    }
  
    @override
    Widget build(BuildContext context) {
      return Scaffold(
        appBar: AppBar(
          title: Text('Woolha.com Flutter Tutorial'),
        ),
        body: Center(
          child: AnimatedCrossFade(
            crossFadeState: _crossFadeState,
            duration: const Duration(seconds: 2),
            reverseDuration: const Duration(seconds: 3),
            firstCurve: Curves.bounceInOut,
            secondCurve: Curves.easeInBack,
            firstChild: const Icon(Icons.text_rotate_up, size: 100),
            secondChild: const Icon(Icons.text_rotate_vertical, size: 200),
            layoutBuilder: (Widget topChild, Key topChildKey, Widget bottomChild, Key bottomChildKey) {
              return Stack(
                overflow: Overflow.visible,
                children: <Widget>[
                  Positioned(
                    key: bottomChildKey,
                    left: 100.0,
                    top: 100.0,
                    child: bottomChild,
                  ),
                  Positioned(
                    key: topChildKey,
                    child: topChild,
                  ),
                ],
              );
            },
          ),
        ),
      );
    }
  }
  

Output:

Flutter - AnimatedCrossFade - Full code

 

Properties

Here's the list of properties you can use to build your desired AnimationCrossFade.

  • Key key: The widget key, used to control if it's should be replaced.
  • Widget firstChild *: The child to be shown when crossFadeState is CrossFadeState.showFirst.
  • Widget secondChild *: The child to be shown when crossFadeState is CrossFadeState.showSecond.
  • Curve firstCurve: The fade curve of the first child. Defaults to Curves.linear.
  • Curve secondCurve The fade curve of the second child. Defaults to Curves.linear. Defaults to Curves.linear.
  • Curse sizeCurve: The curve of the animation between the two children's sizes.
  • AligntmentGeometry alignment: Child alignment when the animation is running.
  • CrossFadeState crossFadeState *: The state to determine whether to show the first or second child.
  • Duration duration *: Duration of the animation.
  • Duration reverseDuration: Duration of the animation when running in reverse.
  • AnimatedCrossFadeBuilder layoutBuilder: A builder for positioning the first child and the second child.

*: required

Summary

That's how to use AnimatedCrossFade. You can also read about:

  • FadeTransition, a widget that animates the opacity of its child widget.
  • AnimatedAlign, a widget for creating animation when the alignment of a widget changes.
  • AnimatedPadding, a widget for creating animation when the padding of a widget changes.
  • AnimatedOpacity, a widget for creating animation when the opacity of a widget changes.
  • AnimatedSwitcher, a widget for creating animation when switching between two widgets.
  • AnimatedSize, a widget that animates its size to match the size of its child.
  • AnimatedContainer, a widget that starts an animation when the value of a property changes.