Menu Close

Flip Business Card – Flutter

In this Flutter app, I show an animation in the form of a business card. It is only a study in which you can see the possibilities of the custom card. It’s an introduction to Flutter’s animations.

Flip Animation Flutter & Dart
Business Card Flip

In the lib Folder we have 2 Files which should look like this:

main.dart
flip_dart_screen.dart

In the main.dart file we use routes to connect and get to the screens:

import 'package:flip_card/flip_dart_screen.dart';
import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      initialRoute: FlipCard.id,
      routes: {
        FlipCard.id: (context) => FlipCard(),
      },
    );
  }
}

Finally the flip_dart_screen.dart file, where you see a Stateful Widget with an Extension of Single TickerProviderStateMixin. This is important for the Animation, we want to build. We sign some values, first the Animation Controller, a boolean which checks if the card flipped or not. The Color, Text and Icon variables are important for the business card and this time we are making those variables global.

In the init-Function we are setting up the Animation Controller with the values in it.

In the Scaffold we are setting up the UI and the function of the App. Important is that we use a Transform Widget, which uses some math of the Dart Programming Language, this is the actual Animation. In the Transform Widget we use a Container and setting up the rest of the business card, before it is flipping.

In the Floating Action Button we check if it is flipped and forwarding or reversing the Animation of the Controller. Here you see why it is important to set up the Color, Text and Icon as a global variable.

import 'package:flutter/material.dart';
import 'dart:math';

class FlipCard extends StatefulWidget {
  static var id = 'flip_card_screen';
  @override
  _FlipCardState createState() => _FlipCardState();
}

class _FlipCardState extends State<FlipCard>
    with SingleTickerProviderStateMixin {
  AnimationController _controller;
  bool _flag = true;
  Color _color = Colors.black;
  Text _textMain = Text(
    'David Koenig',
    style: TextStyle(
      color: Colors.white,
      fontSize: 22.0,
      fontWeight: FontWeight.bold,
    ),
  );
  Text _textPhone = Text(
    '001 234 567 89',
    style: TextStyle(
      color: Colors.white,
      fontSize: 20.0,
    ),
  );
  Icon _iconPhone = Icon(
    Icons.phone,
    size: 20.0,
    color: Colors.white,
  );
  Text _textWeb = Text(
    'www.davidkoenig.de',
    style: TextStyle(
      color: Colors.white,
      fontSize: 20.0,
    ),
  );
  Icon _iconWeb = Icon(
    Icons.public,
    size: 20.0,
    color: Colors.white,
  );

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

    _controller = AnimationController(
      duration: Duration(seconds: 2),
      vsync: this,
      value: 1,
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(
          'Buisness Card',
        ),
        backgroundColor: Colors.black,
      ),
      body: AnimatedBuilder(
        animation: _controller,
        builder: (BuildContext context, Widget child) {
          return Center(
            child: AnimatedBuilder(
              animation: _controller,
              builder: (context, child) {
                return Transform(
                  transform:
                      Matrix4.rotationX((1 - _controller.value) * pi / 2),
                  alignment: Alignment.center,
                  child: Container(
                    height: 190,
                    margin: EdgeInsets.symmetric(horizontal: 20),
                    padding: EdgeInsets.symmetric(vertical: 30),
                    alignment: Alignment.center,
                    decoration: BoxDecoration(
                        borderRadius: BorderRadius.all(Radius.circular(20.0)),
                        color: _color,
                        border: Border.all(color: Colors.grey)),
                    child: Column(
                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
                      children: <Widget>[
                        _textMain,
                        Row(
                          mainAxisAlignment: MainAxisAlignment.center,
                          children: <Widget>[
                            _iconPhone,
                            SizedBox(
                              width: 10.0,
                            ),
                            _textPhone,
                          ],
                        ),
                        Row(
                          mainAxisAlignment: MainAxisAlignment.center,
                          children: <Widget>[
                            _iconWeb,
                            SizedBox(
                              width: 10.0,
                            ),
                            _textWeb,
                          ],
                        ),
                      ],
                    ),
                  ),
                );
              },
            ),
          );
        },
      ),
      floatingActionButton: FloatingActionButton(
        backgroundColor: Colors.black,
        child: Icon(Icons.crop_rotate),
        onPressed: () async {
          if (_flag) {
            await _controller.reverse();
            setState(() {
              _color = Colors.grey;
              _textMain = Text(
                'Happy Coding!',
                style: TextStyle(
                  color: Colors.white,
                  fontSize: 22.0,
                  fontWeight: FontWeight.bold,
                ),
              );
              _textPhone = Text(
                '',
                style: TextStyle(
                  color: Colors.white,
                  fontSize: 0.0,
                ),
              );
              _iconPhone = Icon(
                Icons.phone,
                size: 0.0,
                color: Colors.white,
              );
              _textWeb = Text(
                '',
                style: TextStyle(
                  color: Colors.white,
                  fontSize: 0.0,
                ),
              );
              _iconWeb = Icon(
                Icons.mood,
                size: 40.0,
                color: Colors.white,
              );
            });
            await _controller.forward();
          } else {
            await _controller.reverse();
            setState(() {
              _color = Colors.black;
              _textMain = Text(
                'David Koenig',
                style: TextStyle(
                  color: Colors.white,
                  fontSize: 20.0,
                  fontWeight: FontWeight.bold,
                ),
              );
              _textPhone = Text(
                '001 234 567 89',
                style: TextStyle(
                  color: Colors.white,
                  fontSize: 22.0,
                ),
              );
              _iconPhone = Icon(
                Icons.phone,
                size: 20.0,
                color: Colors.white,
              );
              _textWeb = Text(
                'www.davidkoenig.de',
                style: TextStyle(
                  color: Colors.white,
                  fontSize: 20.0,
                ),
              );
              _iconWeb = Icon(
                Icons.web,
                size: 20.0,
                color: Colors.white,
              );
            });
            await _controller.forward();
          }

          _flag = !_flag;
        },
      ),
    );
  }
}

You can download the project at Github:

https://github.com/DKoenig82/flip_buisness_card_flutter