Kalindu Aragorn
Kalindu Aragorn

Reputation: 25

Flutter SetState from custom widget (or more down the line)

I have a simple flutter app. It has a stateful widget in the Home Page with a simple Scaffold which only has a Column. One of the children in the column is a custom widget called buildBodyLayout(). This widget has its own column with some Text widgets, and another custom widget called buildButton(). This new widget has a button which needs to setState of a variable in the Home view. I pass the value of the variable when calling the widget. But each widget is in its own dart file since I am re-using the same widget in other pages.

How do I setState the main stateful widget from inside custom widgets? If I write everything inside the same page, it all works fine. How do I use a widget in a different dart file to set the sate of a parent widget?

Sample Code

Home Stateful Widget

class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {

  int changeValue; 

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: [
          
          Text("Welcome to my App"),
          Text("The Change Value is: $changeValue"),
          buildBodyLayout(changeValue),
          
        ],
      ),
    );
  }
}

buildBodyLayouot Widget

Widget buildBodyLayout(int value){

  return Column(
    children: [
      Text("Press the + and - Buttons to change Value"),
      buildButtons(value),
    ],
  );

buildButtons Widget Widget buildButtons(int value){

  return Column(
    children: [
      RaisedButton(
        child: Text("Increase Value"),
          onPressed: (){
        value = value + 1;  //THIS SHOULD SET STATE
      })  ,
      RaisedButton(
          child: Text("Decrease Value"),
          onPressed: (){
            value = value - 1;  //THIS SHOULD SET STATE
          })
    ],
  );

}
}

Thank you for any help!

Upvotes: 0

Views: 3315

Answers (1)

Ali Qanbari
Ali Qanbari

Reputation: 3111

Widgets in flutter are classes that extend the widget(StatefulWidget, StatelessWidget) class.

In your code your using functions to build your widgets, which is not recommended.

You can see the difference between class widgets and function widgets here: What is the difference between functions and classes to create reusable widgets?

Aside from that, using function or classes, to solve your problem you need to use a callback.

class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {

  int changeValue = 0; 

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: [
          Text("Welcome to my App"),
          Text("The Change Value is: $changeValue"),
          buildBodyLayout(changeValue,
            addToValue: (int increment){
              setState((){
                changeValue += increment;
              });
            }
          ),
        ],
      ),
    );
  }
}

Widget buildBodyLayout(int value, Function(int newValue) addToValue){
  return Column(
    children: [
      Text("Press the + and - Buttons to change Value"),
      buildButtons(value, addToValue),
    ],
  );
}

Widget buildButtons(int value, Function(int newValue) addToValue){
  return Column(
    children: [
      RaisedButton(
        child: Text("Increase Value"),
          onPressed: (){
            addToValue(1);
          }),
      RaisedButton(
          child: Text("Decrease Value"),
          onPressed: (){
            addToValue(-1);
          })
    ],
  );
 }

You also don't need to put your widgets in different files to reuse them, but it's recommended that you do that.

Upvotes: 3

Related Questions