Open In App

Flutter – Card Flip Animation

Last Updated : 28 Aug, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Flutter is an open-source UI toolkit by Google. It is the favorite framework of many developers to build cross-platform apps because of its easy-to-learn curve. In this article, we are going to code a card flip animation in Flutter. Card flip animation is used in many places where you have to show additional information related to the card item.

Approach

Here to flip the card, we will not use any third-party library. Instead, we will use the Transform Widget paired with Matrix4 and we will use the Tween to animate the transition from from to the back of the card and vice-versa. A sample video is given below to get an idea about what we are going to do in this article.

Syntax

Transform(
transform: Matrix4.rotationY(_animation.value * math.pi),
alignment: Alignment.center,
child: _isFront ? _buildFront() : _buildBack(),
);

Example Project

The below example shows how to animate the card flip in Flutter using just Tween, Transform, and Matrix4 widgets.

Dart




import 'package:flutter/material.dart';
import 'dart:math' as math;
 
void main() {
    runApp(const MyApp());
}
 
class MyApp extends StatelessWidget {
      const MyApp({super.key});
 
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
              title: 'GFG - Flip Card Animation',
              theme: ThemeData(primarySwatch: Colors.green),
              home: const CardFlipAnimation(),
        );
      }
}
 
class CardFlipAnimation extends StatefulWidget {
      const CardFlipAnimation({super.key});
 
      @override
      createState() => _CardFlipAnimationState();
}
 
class _CardFlipAnimationState extends State<CardFlipAnimation> with SingleTickerProviderStateMixin {
      late AnimationController _controller;
      late Animation<double> _animation;
      bool _isFront = true;
      final String _gfgLogo =
 
      @override
      void initState() {
        super.initState();
        _controller = AnimationController(
              vsync: this,
              duration: const Duration(milliseconds: 500),
        );
 
        _animation = Tween<double>(begin: 0, end: 1).animate(_controller)
          ..addListener(() {
            setState(() {});
          });
      }
 
      @override
      void dispose() {
        _controller.dispose();
        super.dispose();
      }
 
      void _flipCard() {
        if (_controller.status != AnimationStatus.forward) {
              if (_isFront) {
                _controller.forward();
              } else {
                _controller.reverse();
              }
              _isFront = !_isFront;
        }
      }
 
      @override
      Widget build(BuildContext context) {
        return Scaffold(
              appBar: AppBar(title: const Text("GFG Flip Card Animation")),
              body: GestureDetector(
                onTap: _flipCard,
                child: Center(
                      child: SizedBox(
                        width: 180,
                        height: 180,
                        child: Transform(
                              transform: Matrix4.rotationY(_animation.value * math.pi),
                              alignment: Alignment.center,
                              child: _isFront ? _buildFront() : _buildBack(),
                        ),
                      ),
                ),
              ),
        );
      }
 
      Widget _buildFront() {
        return ClipRRect(
              borderRadius: BorderRadius.circular(8.0),
              child: Image.network(
                _gfgLogo,
                height: 180.0,
                width: 180.0,
              ),
        );
      }
 
      Widget _buildBack() {
        return Transform(
              alignment: Alignment.center,
              transform: Matrix4.rotationY(3.14),
              child: Container(
                decoration: BoxDecoration(
                      color: Colors.green[700],
                      borderRadius: BorderRadius.circular(10),
                ),
                child: const Center(
                      child: Text(
                        'GeeksforGeeks',
                        style: TextStyle(color: Colors.white, fontSize: 24),
                      ),
                ),
              ),
        );
      }
}


Output:



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads