How to return flip cards to their original position from a widget in another dart file?

0

I'm relatively new to Flutter and have tried to find similar postings to help me but haven't had any luck in getting them to work for me unfortunately. I have an Android Studio program that's basically a game which involves a grid of flip cards. I have the flip cards in one dart file and the app bar in another. I have an iconbutton on the app bar which currently reduces the point count to zero, but I would also like for it to flip all of the flip cards back to their original positions when pressed. I have a global variable called resetBool that I've been trying to use, something like if resetBool == true then toggleCard() maybe. I think I might need to use a key but am having trouble implementing one properly.

Here is the code in the file which contains my appbar:

import 'package:flip_card/flip_card.dart';
import 'package:flutter/material.dart';
import 'gridone.dart' as gridone;
import 'globalVariables.dart';
import 'statenames.dart';

int count;
StateNames stateObject = new StateNames();

class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home>with SingleTickerProviderStateMixin {
  TabController controller;
  @override
  void initState() {
    controller = new TabController(length: 1, vsync: this);
    super.initState();
  }

  @override
  void dispose() {

    controller.dispose();
    super.dispose();
  }

  void changeCount() {
    setState(() {
      counter += 1;
    });
  }

  void decreaseCount() {
    setState(() {
      counter -= 1;
    });
  }



  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(

        title:new Text("License plate game"),
        backgroundColor: Colors.greenAccent,
        actions: <Widget>[
          IconButton(
            icon: Icon(
              Icons.autorenew,
              color: Colors.white,
            ),
            onPressed: () {
              setState(() {
                counter = 0;
                resetBool = true;



              });
            },
          ),

         Center(

          child: Container(
              padding: EdgeInsets.fromLTRB(20, 20, 20, 20),

              child: Text('points: $counter', textAlign: TextAlign.center, style: TextStyle(fontSize: 15),
              )

          ),


         ),

     
        ],






        bottom: new TabBar(
          controller: controller,
          indicatorWeight: 5.0,

          indicatorColor: Colors.green,
          tabs: <Widget> [
            new Tab(icon: new Icon(Icons.image),),
          ],
        ),
      ),
      body: new TabBarView(
        controller: controller,
        children: <Widget>[
          new gridone.GridOne(changeCount, decreaseCount),
        ],
       

      )

    );
  }
}

And here is the code in the file which contains my flip cards:

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flip_card/flip_card.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'statenames.dart';
import 'globalVariables.dart';
import 'Home.dart';
import 'gridtwo.dart' as gridTwo;

StateNames stateObject = new StateNames();
Home homeObject = new Home();

class GridOne extends StatefulWidget {



  final Function updateCounter;
  final Function decreaseCount;
  GridOne(this.updateCounter, this.decreaseCount);




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

class _GridOneState extends State<GridOne>


    with AutomaticKeepAliveClientMixin {

  @override
  bool get wantKeepAlive => true;

  int points = 0;

  @override



  Widget build(BuildContext context) {

  super.build(context);

    return new Scaffold(
     body: new Column(


        children: <Widget> [
          new Expanded(
          child: GridView.count(
         crossAxisCount: 5,
         children: List.generate(52, (index){



           return Card(



             elevation: 0.0,
             margin: EdgeInsets.only(left: 3.0, right: 3.0, top: 9.0, bottom: 0.0),
             color: Color(0x00000000),
             child: FlipCard(

               direction: FlipDirection.HORIZONTAL,
               speed: 1000,
               //(resetBool == true) ? cardKey.currentState.toggleCard() : null,

               onFlipDone: (status) {



                 setState(() {
                   (status)

                   ? widget.decreaseCount()
                   : widget.updateCounter();

                 });



                 if (counter == 25) {
                   Fluttertoast.showToast(
                       msg: "You've got 25 states! Wow!",
                       toastLength: Toast.LENGTH_SHORT,
                       gravity: ToastGravity.BOTTOM_LEFT,
                       timeInSecForIosWeb: 1,
                       backgroundColor: Colors.red,
                       textColor: Colors.white,
                       fontSize: 16.0);
                 };

                 print(counter);




               },
               front: Container(
                 decoration: BoxDecoration(
                   color: Color(0xFF006666),
                   borderRadius: BorderRadius.all(Radius.circular(8.0)),
                 ),
                 child: Column(
                   mainAxisAlignment: MainAxisAlignment.center,

                    crossAxisAlignment: CrossAxisAlignment.stretch,
                   children: <Widget>[
                     FittedBox(fit:BoxFit.fitWidth,
                     child: Text(stateObject.stateNames[index], style: TextStyle(fontFamily: 'Architects Daughter', color: Colors.white), )
                         //Theme.of(context).textTheme.headline
                 ),
                     Text('',
                         style: Theme.of(context).textTheme.body1),
                   ],
                 ),
               ),
               back: Container(
                 decoration: BoxDecoration(
                   color: Color(0xFF006666),
                   borderRadius: BorderRadius.all(Radius.circular(8.0)),

                 ),
                 child: Column(
                   mainAxisAlignment: MainAxisAlignment.center,
                   children: <Widget>[

                     Image(image: AssetImage(stateObject.licensePlatePaths[index])),
                     //Text('',
                         //style: Theme.of(context).textTheme.body1),
                   ],

                 ),
               ),
             ),
           );

         })
     )
          )
        ]
     ),
    );

  }
}


android-studio
flutter
dart
gridview
key
asked on Stack Overflow Nov 6, 2020 by glitter_magnolia • edited Nov 7, 2020 by glitter_magnolia

1 Answer

0

The solution is to use currentState.toggleCard(); for the cards that are facing Back when the IconButton is clicked.

Basically, what I did is I gave keys to each card at initState method.

List<GlobalKey<FlipCardState>> cardKeys = [];

 @override
  void initState() {
    List.generate(52, (index) {
      cardKeys.add(GlobalKey<FlipCardState>());
    });
    super.initState();
  }

Don't forget to put the key to widget

FlipCard(key: cardKeys[index], ... )

Then, call resetCards method below when the button is clicked. If the card is facing back then toggle logic.

void resetCards() {
    cardKeys.forEach((element) {
      if (!element.currentState.isFront) {
        element.currentState.toggleCard();
      }
    });
    setState(() {});
  }    

You need to call a method on the parent widget, that would be triggered in the child widget. For that, please check this stackoverflow link

Full working code:

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

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        // This is the theme of your application.
        //
        // Try running your application with "flutter run". You'll see the
        // application has a blue toolbar. Then, without quitting the app, try
        // changing the primarySwatch below to Colors.green and then invoke
        // "hot reload" (press "r" in the console where you ran "flutter run",
        // or simply save your changes to "hot reload" in a Flutter IDE).
        // Notice that the counter didn't reset back to zero; the application
        // is not restarted.
        primarySwatch: Colors.blue,
        // This makes the visual density adapt to the platform that you run
        // the app on. For desktop platforms, the controls will be smaller and
        // closer together (more dense) than on mobile platforms.
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: Home(),
    );
  }
}

class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> with SingleTickerProviderStateMixin {
  TabController controller;
  int counter = 0;
  final GridOneController myController = GridOneController();

  @override
  void initState() {
    controller = new TabController(length: 1, vsync: this);
    super.initState();
  }

  @override
  void dispose() {
    controller.dispose();
    super.dispose();
  }

  void changeCount() {
    setState(() {
      counter += 1;
    });
  }

  void decreaseCount() {
    setState(() {
      counter -= 1;
    });
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
        appBar: new AppBar(
          title: new Text("License plate game"),
          backgroundColor: Colors.greenAccent,
          actions: <Widget>[
            IconButton(
              icon: Icon(
                Icons.autorenew,
                color: Colors.white,
              ),
              onPressed: () {
                setState(() {
                  counter = 0;
                  myController.resetCards();
                });
              },
            ),
            Center(
              child: Container(
                  padding: EdgeInsets.fromLTRB(20, 20, 20, 20),
                  child: Text(
                    'points: $counter',
                    textAlign: TextAlign.center,
                    style: TextStyle(fontSize: 15),
                  )),
            ),
          ],
          bottom: new TabBar(
            controller: controller,
            indicatorWeight: 5.0,
            indicatorColor: Colors.green,
            tabs: <Widget>[
              new Tab(
                icon: new Icon(Icons.image),
              ),
            ],
          ),
        ),
        body: new TabBarView(
          controller: controller,
          children: <Widget>[
            new GridOne(counter, myController),
          ],
        ));
  }
}

class GridOneController {
  void Function() resetCards;
}

class GridOne extends StatefulWidget {
  int counter;
  final GridOneController controller;

  GridOne(this.counter, this.controller);

  @override
  _GridOneState createState() => _GridOneState(controller);
}

class _GridOneState extends State<GridOne> {
  _GridOneState(GridOneController _controller) {
    _controller.resetCards = resetCards;
  }

  int points = 0;

  void increaseCounter() {
    widget.counter += 1;
  }

  void decreaseCounter() {
    widget.counter -= 1;
  }

  void resetCards() {
    cardKeys.forEach((element) {
      if (!element.currentState.isFront) {
        element.currentState.toggleCard();
      }
    });
    setState(() {});
  }

  List<GlobalKey<FlipCardState>> cardKeys = [];

  @override
  void initState() {
    List.generate(52, (index) {
      cardKeys.add(GlobalKey<FlipCardState>());
    });
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    print(cardKeys.length);
    return new Scaffold(
      body: new Column(children: <Widget>[
        new Expanded(
            child: GridView.count(
                crossAxisCount: 5,
                children: List.generate(52, (index) {
                  return Card(
                    elevation: 0.0,
                    margin: EdgeInsets.only(
                        left: 3.0, right: 3.0, top: 9.0, bottom: 0.0),
                    color: Color(0x00000000),
                    child: new FlipCard(
                      key: cardKeys[index],
                      direction: FlipDirection.HORIZONTAL,
                      speed: 1000,
                      onFlipDone: (status) {
                        setState(() {
                          (status) ? decreaseCounter() : increaseCounter();
                        });

                        if (widget.counter == 25) {
                          Fluttertoast.showToast(
                              msg: "You've got 25 states! Wow!",
                              toastLength: Toast.LENGTH_SHORT,
                              gravity: ToastGravity.BOTTOM_LEFT,
                              timeInSecForIosWeb: 1,
                              backgroundColor: Colors.red,
                              textColor: Colors.white,
                              fontSize: 16.0);
                        }
                        ;

                        print(widget.counter);
                      },
                      front: Container(
                        decoration: BoxDecoration(
                          color: Color(0xFF006666),
                          borderRadius: BorderRadius.all(Radius.circular(8.0)),
                        ),
                        child: Column(
                          mainAxisAlignment: MainAxisAlignment.center,
                          crossAxisAlignment: CrossAxisAlignment.stretch,
                          children: <Widget>[
                            FittedBox(
                                fit: BoxFit.fitWidth,
                                child: Text(
                                  'FRONT',
                                  style: TextStyle(color: Colors.white),
                                )
                                //Theme.of(context).textTheme.headline
                                ),
                            Text(
                              '',
                            ),
                          ],
                        ),
                      ),
                      back: Container(
                        decoration: BoxDecoration(
                          color: Color(0xFF006666),
                          borderRadius: BorderRadius.all(Radius.circular(8.0)),
                        ),
                        child: Column(
                          mainAxisAlignment: MainAxisAlignment.center,
                          children: <Widget>[Text('BACK')],
                        ),
                      ),
                    ),
                  );
                })))
      ]),
    );
  }
}
answered on Stack Overflow Nov 6, 2020 by morpheus

User contributions licensed under CC BY-SA 3.0