Home > Mobile >  how to get a bool in a stateful widget to change a counter in it's parent stateful widget
how to get a bool in a stateful widget to change a counter in it's parent stateful widget

Time:01-14

I'm quite new to flutter and i'm struggling to get my head around passing variables up the widget tree. I've written a very simple code to demonstrate what i'm trying to achieve and I was hoping someone could please spell it out for me.

I have a parent Stateful widget with a counter in it:

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

  @override
  State<ParentWidget> createState() => _ParentWidgetState();
}

class _ParentWidgetState extends State<ParentWidget> {
  int Counter = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          children: [
            SizedBox(
              height: 100,
            ),
            Button(),
          ],
        ),
      ),
    );
  }
}

then I have another Stateful Widget with the button and bool in it:

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

  @override
  State<Button> createState() => _ButtonState();
}

class _ButtonState extends State<Button> {
  bool buttonPressed = false;
  @override
  Widget build(BuildContext context) {
    return InkWell(
      onTap: () {
        setState(() {
          buttonPressed = !buttonPressed;
          print(buttonPressed);
        });
      },
      child: Container(
        color: kWhite,
        height: 50,
        width: 50,
      ),
    );
  }
}

I've looked at some of the other answers (using callbacks?) but am struggling to understand how it actually works and how I would implement it into my code

How do I pass the bool variable up the tree to change the counter?

thanks so much and any help would be greatly appreciated

CodePudding user response:

Add the callback function in the Button widget that returns the state of the button pressed.

In Parent widget, add the argument for the callback function which returns the button pressed state.

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

  @override
  State<ParentWidget> createState() => _ParentWidgetState();
}

class _ParentWidgetState extends State<ParentWidget> {
  int Counter = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          children: [
            const SizedBox(
              height: 100,
            ),
            Button(isPressed: (isPressed) => print(isPressed)),  <-- updated
          ],
        ),
      ),
    );
  }
}

class Button extends StatefulWidget {
  final Function(bool) isPressed;   <-- updated

  const Button({Key? key, required this.isPressed}) : super(key: key);   <-- updated

  @override
  State<Button> createState() => _ButtonState();
}

class _ButtonState extends State<Button> {
  bool buttonPressed = false;
  @override
  Widget build(BuildContext context) {
    return InkWell(
      onTap: () {
        setState(() {
          buttonPressed = !buttonPressed;
          print(buttonPressed);
        });
         widget.isPressed(buttonPressed);  <-- updated
      },
      child: Container(
        color: Colors.white,
        height: 50,
        width: 50,
      ),
    );
  }
}

CodePudding user response:

This is how to pass data to parent widget using a callback,

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

  @override
  State<ParentWidget> createState() => _ParentWidgetState();
}

class _ParentWidgetState extends State<ParentWidget> {
  int Counter = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          children: [
            SizedBox(
              height: 100,
            ),
            Button(
              // here you will get the bool
              onBtnPressed: (val) {
                print(val);
              },
            ),
          ],
        ),
      ),
    );
  }
}

class Button extends StatefulWidget {
  const Button({required this.onBtnPressed, Key? key}) : super(key: key);

  // add this here, this function will act as the callback
  final Function onBtnPressed;

  @override
  State<Button> createState() => _ButtonState();
}

class _ButtonState extends State<Button> {
  bool buttonPressed = false;

  @override
  Widget build(BuildContext context) {
    return InkWell(
      onTap: () {
        setState(() {
          buttonPressed = !buttonPressed;
          print(buttonPressed);
        });
        widget.onBtnPressed(buttonPressed);
      },
      child: Container(
        color: kWhite,
        height: 50,
        width: 50,
      ),
    );
  }
}
  • Related