Solved: Update a variable inside stateful class from another widget / class

Question

Asked by Bakhtawar on December 21, 2021 (source).

I am realtively new to flutter. HOW TO UPDATE a private variable inside a stateteful flutter widget from another class.

  • I KNOW ONE WAY IS TO DECLARE IT GLOBALLY but THIS WILL CHANGE MANY THINGS. FOR EXAMPLE: This card is like a button. There are many buttons generated from this class. If I make _temp a global variable; i will lose the sole purpose i.e it being unique for all buttons, all categories, all foods.

  • another way can be to create a method but i am not sure how t aces it from outside the widget? e.g:

    void reset() { _temp = 0; }

Please see the code to understand the problem:

class ReusableCard extends StatefulWidget {
  ReusableCard({

    required this.itemName,
  });

  final String? itemName;

  @override
  State<ReusableCard> createState() => _ReusableCardState();
}

class _ReusableCardState extends State<ReusableCard> {

 // HOW TO UPDATE THIS int _temp (BELOW) FROM ANOTHER CLASS?
 // I KNOW I CAN DECLARE IT GLOBALLY but THIS WILL CHANGE MANY THINGS.
 //  FOR EXAMPLE: This card is like abutton. There are many buttons generated from this class. If I make _temp a global variable; i will lose the sole purpose i.e it being unique for all buttons, all categories, all foods.


  int _temp = 0;
       
  @override
  Widget build(BuildCon .......

UPDATE

Class where i am trying to reset temp i.e calling: "reusableCardKey.currentState?.temp = 0;":

    import 'package:flutter/material.dart';
    import 'buttonn.dart';
    import 'cardbutton.dart';
    
    var foodCategory = ValueNotifier(0);
    
    class Sidebar extends StatefulWidget {
      const Sidebar({Key? key}) : super(key: key);
    
      @override
      State<Sidebar> createState() => _SidebarState();
    }
    
    class _SidebarState extends State<Sidebar> {
      final GlobalKey<ReusableCardState> reusableCardKey = GlobalKey();
      @override
      Widget build(BuildContext context) {
        return Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
//Buttonn basically is skeleton for elevated button.
            Buttonn(
              col: Colors.lightBlue.shade400,
              tex: 'Parathas',
              fixedsize: const Size(15, 180),
//buttonFunc is basically (){} of elevated button.
              buttonFunc: () {
                setState(() {
                  foodCategory.value = 0;
                  reusableCardKey.currentState?.temp = 0;
                });
              },
            ),
            const SizedBox(height: 20.0),
            Buttonn(
              col: Colors.lightBlue.shade400,
              tex: 'Chai',
              fixedsize: const Size(15, 180),
              buttonFunc: () {
                
                setState(() {
                  foodCategory.value = 1;
    reusableCardKey.currentState?.temp = 0;
                  print(reusableCardKey.currentState?.temp);
                });
              },
            ),
            const SizedBox(height: 20.0),
            Buttonn(
              col: Colors.lightBlue.shade400,
              tex: 'Others',
              fixedsize: const Size(15, 180),
              buttonFunc: () {
                foodCategory.value = 2;
    
                reusableCardKey.currentState?.temp = 0;
                print(reusableCardKey.currentState?.temp);
              },
            ),
            const SizedBox(height: 20.0),
            Buttonn(
              col: Colors.lightBlue.shade400,
              tex: 'pending',
              fixedsize: const Size(15, 50),
              buttonFunc: () {
                foodCategory.value = 3;
                reusableCardKey.currentState?.temp = 0;
              },
            ),
          ],
        );
      }
    }

Answer

Question answered by omar h (source).

You can do that by the following steps:

  1. Make _ReusableCardState and _temp not private (i.e remove the underscore)
  2. Make ReusableCard constructor takes an optional Key and calls its super constructor with this key. like this ReusableCard({Key? key, required this.itemName}) : super(key: key);
  3. Define a key with the state like this final GlobalKey<ReusableCardState> reusableCardKey = GlobalKey(); in the class that calls ReusableCard
  4. Pass this key to the ReusableCard like this ReusableCard(key: reusableCardKey, itemName: "First Item")
  5. Now you can use this key (reusableCardKey) to modify temp through reusableCardKey.currentState.temp = 28;
DART FLUTTER
SHARE: