Search code examples
flutterdartdart-pubflutter-getx

How to use controller in flip_card Widget Flutter?


I am using flip_card package for flipping the cards in my quiz application. I have a next button to change the question and answer on both sides of card. But the problem is if the card is on answer side(back side), clicking the next button shows the answer of next question. I want to automatically reverse the card with next button click, if it is in answer side.

pub dev link : flip_card

github link : flip_card Github



class Practice extends GetView {
  final ShowcaseController cardController = Get.put(ShowcaseController());
  final PracticeController practiceController = Get.put(PracticeController());

  final subjectName;
  Practice({this.subjectName});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.blue[100],
      body: Center(
        child: Obx(
          () => 
          //Flip_card Code
          FlipCard(
            direction: FlipDirection.HORIZONTAL,
            front: Container(
              color: Colors.white,
              child: Text(cardController.cards[practiceController.cardIndex.toInt()]["question"]),
            ),
            back: Container(
              color: Colors.red,
              child: Text(cardController.cards[practiceController.cardIndex.toInt()]["answer"]),
            ),
          ),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        child: Text("Next"),
        onPressed: () {
          practiceController.cardIndex++;
        },
      ),
    );
  }
}



Solution

  • I wasn't seeing any immediately obvious way to track that state of the card. But here's one solution.

    General idea is to create a boolean that updates on card flip, and if the Next button is hit, if the card is flipped, it will flip back to the front before moving onto the next index. This will also require keeping the GlobalKey in the Getxclass.

    Add the following to your PracticeController class.

    GlobalKey<FlipCardState> cardKey = GlobalKey<FlipCardState>();
    
      bool cardIsFlipped = false;
    
      void updateCardIsFlipped() => cardIsFlipped = !cardIsFlipped;
    
      Future<void> nextQuestion() async {
        if (cardIsFlipped) {
          cardKey.currentState.toggleCard();
        }
        await Future.delayed(const Duration(milliseconds: 200), () {
          cardIndex++;
        }); // needs time for the flip animation to complete before moving to the next question
      }
    

    Then a few changes to your Scaffold and you're good to go.

    Scaffold(
          backgroundColor: Colors.blue[100],
          body: Center(
            child: Obx(
              () => FlipCard(
                direction: FlipDirection.HORIZONTAL,
                key: practiceController.cardKey, // using key from Getx class
                onFlip: () => practiceController.updateCardIsFlipped(), // updating bool on every flip
                front: Container(
                    color: Colors.white,
                    child: Text(cardController
                            .cardsMap[practiceController.cardIndex.toInt()]
                        ["question"])),
                back: Container(
                  color: Colors.red,
                  child: Text(cardController
                      .cardsMap[practiceController.cardIndex.toInt()]["answer"]),
                ),
              ),
            ),
          ),
          floatingActionButton: FloatingActionButton(
            child: const Text("Next"),
            onPressed: () => practiceController.nextQuestion(), // function from Getx class
          ),
        );
    

    enter image description here