'I need to know how i can call a variable in from a stateful widget to a stateless one

I need to call a variable from a stateful widget to another class but it's not working fine.

Below is my code snippet

class donateMain extends StatefulWidget {
const donateMain({Key? key}) : super(key: key);

@override
State<donateMain> createState() => _donateMainState();
}

class _donateMainState extends State<donateMain> {
static var currentAmount = 0;    //i want to call currentAmount

void _setAmount(int amount) {
setState(() {
  currentAmount = amount;
});
}

 @override
 Widget build(BuildContext context) {
 return Scaffold(
  appBar: AppBar(
    centerTitle: true,
    title: Text('$currentAmount'),
  ),
  body: ButtonsRow(
    onSetAmount: _setAmount,
  ),
);
}
}

From the donateMain, i want to call the current amount to the button row below.

class ButtonsRow extends StatelessWidget {
const ButtonsRow({
Key? key,
required this.onSetAmount,
}) : super(key: key);

final void Function(int) onSetAmount;
@override
Widget build(BuildContext context) {
return SafeArea(
    child: SingleChildScrollView(
        child: Column(children: [
  Container(
    child: Center(
      child: Text(
        "€" +($currentAmount),   // this is where i want to access current amount
        style: TextStyle(
            fontSize: 35, color: Colors.white, fontWeight: FontWeight.bold),
        textAlign: TextAlign.center,
      ),
    ),

Can anyone help me out? Thank you!



Solution 1:[1]

In order to communicate between the two widgets (donateMain and ButtonsRow) you'll need a middle-man, like a state-management provided sort of service. But if you want to keep things simple, just pass it via the constructor the same way you're passing the onSetAmount function.

Then, to trigger a change from the ButtonsRow, just call the callback method onSetAmount from inside by wrapping the Container widget inside a GestureDetector. This is what your updated ButtonsRow widget will look like:


class ButtonsRow extends StatelessWidget {
  const ButtonsRow({
    Key? key,
    required this.amount,
    required this.onSetAmount,
  }) : super(key: key);

  final void Function(int) onSetAmount;
  final int amount;
  
  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: SingleChildScrollView(
        child: Column(children: [
          GestureDetector(
            onTap: () {
              onSetAmount(100);
            },
            child: Container(
            child: Center(
              child: Text(
                "€$amount",   // this is where i want to access current amount
                style: TextStyle(
                  fontSize: 35, color: Colors.black, fontWeight: FontWeight.bold),
                textAlign: TextAlign.center,
              ),
            )
           )
          )
        ]
       )
      )
    );
  }
}

Here's a Gist I created with the running code (make sure to run it on DartPad.dev to check it out). I still think you should invest a bit of time now and migrate this using a more robust approach like using Provider state management, so in this Gist I've also provided the alternate approach using a simple state management solution like Provider, which will make your app more robust and maintainable as it grows.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1