Home > Software design >  I need to know how i can call a variable in from a stateful widget to a stateless one
I need to know how i can call a variable in from a stateful widget to a stateless one

Time:03-10

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!

CodePudding user response:

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.

  • Related