Physical Address

304 North Cardinal St.
Dorchester Center, MA 02124

flutter tinder

Tinder like swipe cards in Flutter app

Creating a tinder like app in Flutter

Implement Tinder like swipe card feature using flutter is quite easy because of the powerful widget provided by Flutter sdk. In here you will learn how to implement swipe card function in Flutter using several known widgets.

Everything in the flutter is some kind of widget. The Draggable widget will give an ability to drag the child widget and you can control what you need to do when dragging the widget.

Solution breakdown

First of all, you need to think about the widget Structure. This is the widget structure you need to follow.

  • Create a Card widget using the card class.
  • Wrap the Card widget inside the Positioned widget.
  • Positioned those card widgets inside the Stack widget.
  • Wrap the card inside Draggable widget to give the ability to drag and drop.

Implementation

Let’s think about what are the properties need to change for each card.

First, we need to change the colour and the position from the top of the stack widget. If we don’t change the position from the top, each card will be stack the top left corner and we cannot see each card separately. Because that’s the default behaviour of the stack widget.

So Let’s start with Creating MatchCard Class. You can set the colour and the position for each card using this MatchCard class.

class MatchCard {
  int redColor = 0;
  int greenColor = 0;
  int blueColor = 0;
  double margin = 0;

  MatchCard(int red, int green, int blue, double marginTop) {
    redColor = red;
    greenColor = green;
    blueColor = blue;
    margin = marginTop;
  }
}

Create a list of cards

You can define a function to get a list of cards. In here I create 3 cards and append those cards to the Widget List.

List _getMatchCard() {
    List cards = new List();
    cards.add(MatchCard(255, 0, 0, 10));
    cards.add(MatchCard(0, 255, 0, 20));
    cards.add(MatchCard(0, 0, 255, 30));

    List cardList = new List();

    for (int x = 0; x < 3; x++) {
      cardList.add(Positioned(
        top: cards[x].margin,
        child: Draggable(
          onDragEnd: (drag){
              _removeCard(x);
          },
          childWhenDragging: Container(),
          feedback: Card(
            elevation: 12,
            color: Color.fromARGB(255, cards[x].redColor, cards[x].greenColor, cards[x].blueColor),
            shape:
                RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
            child: Container(
              width: 240,
              height: 300,
            ),
          ),
          child: Card(
            elevation: 12,
            color: Color.fromARGB(255, cards[x].redColor, cards[x].greenColor, cards[x].blueColor),
            shape:
                RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
            child: Container(
              width: 240,
              height: 300,
            ),
          ),
        ),
      ));
    }

    return cardList;
  }

The _removeCard method is not defined yet and I will define it in the end. You can see some interesting attributes inside Draggable widget. Let’s discuss what are those attributes.

  • feedback – We must provide some kind of Widget for this. This is the widget which is shown when a drag event is happening. In this scenario, we need to show the same actual card widget when dragging.
  • childWhenDragging – The widget to display instead of [child] when one or more drags are underway. For that, you can give an empty container. Then It will don’t show any child widget when dragging.
  • onDragEnd – This call when the drag ends. We can remove the card when drag get completed.

Next, we need to call _getMatchCard() inside the initState method and assign those List of the widget to the List cardList.

Finally, you need to remove the card after each drag gets completed. For that, I am gone to define a method called _removeCard. Inside that method, I am gone to call setState and inside that, you can remove each card widget.

initState – This is the first method called when the widget is created (after the class constructor, of course.)

https://flutterbyexample.com/stateful-widget-lifecycle/

Remove widget from the list

void _removeCard(index) {
    setState(() {
      cardList.removeAt(index);
    });
  }

Check swipe direction in Draggable

You can check the swipe direction using onDragEnd method. When its trigger it comes with DraggableDetails parameter. It contains offset with direction value. If the direction is greater than 1 it can consider as a left swipe and if not it will be a right swipe.

     onDragEnd: (drag){
            if(drag.offset.direction > 1){
              print("Swipe left");
            } else {
              print("Swipe right");
            }
          },

Conclusion

I hope you get the idea about these widgets and If you are stuck in any place please check this is the full code

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Card Stack'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  List<Widget> cardList;

  void _removeCard(index) {
    setState(() {
      cardList.removeAt(index);
    });
  }

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    cardList = _getMatchCard();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Stack(
          alignment: Alignment.center,
          children: cardList,
        ),
      ),
    );
  }

  List<Widget> _getMatchCard() {
    List<MatchCard> cards = new List();
    cards.add(MatchCard(255, 0, 0, 10));
    cards.add(MatchCard(0, 255, 0, 20));
    cards.add(MatchCard(0, 0, 255, 30));

    List<Widget> cardList = new List();

    for (int x = 0; x < 3; x++) {
      cardList.add(Positioned(
        top: cards[x].margin,
        child: Draggable(
          onDragEnd: (drag){
              _removeCard(x);
          },
          childWhenDragging: Container(),
          feedback: Card(
            elevation: 12,
            color: Color.fromARGB(255, cards[x].redColor, cards[x].greenColor, cards[x].blueColor),
            shape:
                RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
            child: Container(
              width: 240,
              height: 300,
            ),
          ),
          child: Card(
            elevation: 12,
            color: Color.fromARGB(255, cards[x].redColor, cards[x].greenColor, cards[x].blueColor),
            shape:
                RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
            child: Container(
              width: 240,
              height: 300,
            ),
          ),
        ),
      ));
    }

    return cardList;
  }
}