user13002252
user13002252

Reputation:

Set State doesn't change the value just if hot reload the page

I have the following situation

Column(
  children: [
    Tabs(),
    getPage(),
], 
),

the getPage method

   Widget getPage() {
      if (tab1IsSelected == true) {
        return Container(
          child: Center(
            child: Text('Tab1'),
          ),
        );
      }
      if (tab1IsSelected == false) {
        return Container(
          child: Center(
            child: Text('Tab2'),
          ),
        );
      }
    }

and globally I have declared a variable

bool tab1IsSelected = true;

In the Tabs Class (statefull):

class Tabs extends StatefulWidget {
  @override
  _TabsState createState() => _TabsState();
}

class _TabsState extends State<Tabs> {
  @override
  Widget build(BuildContext context) {
    return Row(
      children: [
        Expanded(
          child: GestureDetector(
            onTap: () {
              setState(() {
                tab1IsSelected = true;
              });
            },
            child: Container(
              decoration: BoxDecoration(
                color: tab1IsSelected ? primary : second,
              ),
              child: Padding(
                padding:
                    EdgeInsets.only(top: 1.5 * SizeConfig.heightMultiplier),
                child: Center(
                  child: Text(
                    'New Hunt',
                    style: Theme.of(context).textTheme.bodyText1,
                  ),
                ),
              ),
            ),
          ),
        ),
        Expanded(
          child: GestureDetector(
            onTap: () {
              setState(() {
                tab1IsSelected = false;
              });
            },
            child: Container(
              decoration: BoxDecoration(
                color: tab1IsSelected ? second : primary,
              ),
              child: Padding(
                padding:
                    EdgeInsets.only(top: 1.5 * SizeConfig.heightMultiplier),
                child: Center(
                  child: Text(
                    'My Hunts',
                    style: Theme.of(context).textTheme.bodyText2,
                  ),
                ),
              ),
            ),
          ),
        ),
      ],
    );
  }
}


I change the value of that bool, but only if I hot reload the page the content is changing. Why? Can you guide me please?

I've tried to use ? : in that Column but the same result and if I declare that variable in the Main Class where the Column is, I can't access it in the Tabs class, so that's why I declared it globally, maybe that's the cause I have to hot reload, but how can I implement that to do what I want. Thank you in advance

Upvotes: 2

Views: 2177

Answers (3)

Archie
Archie

Reputation: 151

You can try to handle the setstate in the parent class holding the Tab Widget then pass a the function to tab class and execute it in the gesture detector.

Upvotes: 0

ddalbosco
ddalbosco

Reputation: 169

If you want to rebuild a widget when something in its state changes you need to call the setState() of the widget. The variable is referenced to the State class and when you call setState() Flutter will rebuild the widget itself by calling the build() method of the State class.

If you want to have some variables outside the widgets I suggest you to use a state management approach listed here: https://flutter.dev/docs/development/data-and-backend/state-mgmt/options.

For example you could use Provider to store the active tab and reference the provider variable in both widgets.

Upvotes: 0

EdwynZN
EdwynZN

Reputation: 5601

setState is inside _TabsState so it will only affect/rebuilt that particular widget, not getPage(), you could try using ValueChanged<bool> to retrieve the new value and then using setState in the widget that wraps the getPage()

class Tabs extends StatefulWidget {
  final ValueChanged<bool> onChanged;

  Tabs({this.onChanged});


  @override
  _TabsState createState() => _TabsState();
}

class _TabsState extends State<Tabs> {
  @override
  Widget build(BuildContext context) {
    return Row(
      children: [
        Expanded(
          child: GestureDetector(
            onTap: () => widget.onChanged(true), //pass the value to the onChanged
            child: Container(
              decoration: BoxDecoration(
                color: tab1IsSelected ? primary : second,
              ),
              child: Padding(
                padding:
                    EdgeInsets.only(top: 1.5 * SizeConfig.heightMultiplier),
                child: Center(
                  child: Text(
                    'New Hunt',
                    style: Theme.of(context).textTheme.bodyText1,
                  ),
                ),
              ),
            ),
          ),
        ),
        Expanded(
          child: GestureDetector(
            onTap: () => widget.onChanged(false), //pass the value to the onChanged
            child: Container(
              decoration: BoxDecoration(
                color: tab1IsSelected ? second : primary,
              ),
              child: Padding(
                padding:
                    EdgeInsets.only(top: 1.5 * SizeConfig.heightMultiplier),
                child: Center(
                  child: Text(
                    'My Hunts',
                    style: Theme.of(context).textTheme.bodyText2,
                  ),
                ),
              ),
            ),
          ),
        ),
      ],
    );
  }
}

Now on the widget with the column (That should be a StatefulWidget for setState to work)

Column(
  children: [
    Tabs(
      onChanged: (bool value) => setState(() => tab1IsSelected = value);
    ),
    getPage(),
  ], 
),

everytime you change the value of tab1IsSelected it will update getPage()

Upvotes: 1

Related Questions