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,
),
);
}
}