Flutter AnimatedSwitcher Widget Examples: Flip Card

AnimatedSwitcher widget replaces its previously set as child with a new widget using transition animation.

By default, fade animation is used to switch widgets. We can use AnimatedSwitcher’s transitionBuilder property to apply custom animation.

Flip Card

To create a flip card, we use AnimatedSwitcher to switch between 2 widgets which are front and rear ones. Rotation animation is set in transitionBuilder.

import 'dart:math';

import 'package:flutter/material.dart';

class FlipCardPage extends StatefulWidget {
  @override
  _FlipCardPageState createState() => _FlipCardPageState();
}

class _FlipCardPageState extends State<FlipCardPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flip Animation'),
      ),
      body: Container(
        width: double.infinity,
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            FlipCard(),
          ],
        ),
      ),
    );
  }
}

class FlipCard extends StatefulWidget {
  @override
  _FlipCardState createState() => _FlipCardState();
}

class _FlipCardState extends State<FlipCard>
    with SingleTickerProviderStateMixin {
  bool _isFront = true;

  @override
  void initState() {
    super.initState();
  }

  Widget _frontCard() {
    return Container(
      key: ValueKey(true),
      color: Colors.orangeAccent,
      width: 200,
      height: 200,
      child: Center(
          child: Text(
        'Front',
        style: TextStyle(color: Colors.white, fontSize: 48),
      )),
    );
  }

  Widget _rearCard() {
    return Container(
      key: ValueKey(false),
      color: Colors.orange,
      width: 200,
      height: 200,
      child: Center(
          child: Text(
        'Rear',
        style: TextStyle(color: Colors.white, fontSize: 48),
      )),
    );
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () {
        setState(() {
          _isFront = !_isFront;
        });
      },
      child: AnimatedSwitcher(
        child: _isFront ? _frontCard() : _rearCard(),
        duration: Duration(seconds: 1),
        transitionBuilder: (Widget child, Animation<double> animation) {
          final rotate = Tween(begin: pi, end: 0.0).animate(animation);

          return AnimatedBuilder(
              animation: rotate,
              child: child,
              builder: (BuildContext context, Widget child) {
                final angle = (ValueKey(_isFront) != widget.key)
                    ? min(rotate.value, pi / 2)
                    : rotate.value;
                return Transform(
                  transform: Matrix4.rotationY(angle),
                  child: child,
                  alignment: Alignment.center,
                );
              });
        },
        switchInCurve: Curves.easeInCubic,
        switchOutCurve: Curves.easeOutCubic,
      ),
    );
  }
}

Leave a Comment

Your email address will not be published. Required fields are marked *

By continuing to use the site, you agree to the use of cookies. more information

The cookie settings on this website are set to "allow cookies" to give you the best browsing experience possible. If you continue to use this website without changing your cookie settings or you click "Accept" below then you are consenting to this.

Close