ujwal dhakal
ujwal dhakal

Reputation: 2459

State not chaning for switch tiles inside popmenu item flutter

This is my widget

  Widget sortingWidget() {
    return new PopupMenuButton<int>(
      itemBuilder: (context) => [
        PopupMenuItem(
          value : this._popMenuBtn,
          child: SwitchListTile(
            title: const Text('Sort by experience'),
            value: this._sortByExperienceSwitch,
            onChanged: handleExperienceSortingToggle,
          ),
        )
      ],
    );
  }

And this is my toggle handle function

  handleExperienceSortingToggle(value) {

    this.setState(() {
      this._sortByExperienceSwitch = value;
    }
    );
  }

But when I change state it is not changing and only changes when the popup-menu button is closed and open

Upvotes: 1

Views: 1303

Answers (3)

Alvey
Alvey

Reputation: 53

I had a similar problem, i used a StatefulBuilder to solve it. Here is how i used it for my switch

PopupMenuButton(
                    itemBuilder: (BuildContext context) => [
                      PopupMenuItem(
                        child:
                        StatefulBuilder(
                          builder: (context, setState) {
                            return Switch(
                              value: darkMode,
                              onChanged: (bool value) {
                                setState(() {
                                  darkMode = value;
                                });
                                this.setState(() {});
                              },
                            );
                          },
                        ),
                      ),
                    ]
                )

Upvotes: 3

ltk
ltk

Reputation: 1292

The child of PopIpMenuItem is stateless, so it does not redraw when the value changes.

Either 1) you create a stateful widget for the child,

PopupMenuItem(
  child: PopupMenuSwitchItem(
    value: _value,
    onValueChanged: _handleValueChanged,
    ),
  ),

...

class PopupMenuSwitchItem extends StatefulWidget {
  PopupMenuSwitchItem({
    Key key,
    this.value,
    this.onValueChanged,
  }) : super(key: key);

  final bool value;
  final ValueChanged<bool> onValueChanged;

  @override
  _PopupMenuSwitchItemState createState() =>
      _PopupMenuSwitchItemState(this.value);
}

class _PopupMenuSwitchItemState extends State<PopupMenuSwitchItem> {
  _PopupMenuSwitchItemState(bool value) {
    this._state = value;
  }

  bool _state;

  void _handleValueChanged(String value) {
    widget.onValueChanged(value);
  }

or 2) if you are using a provider to manage the state, just wrap your switch in a Consumer to force the widget to redraw when the value changes.

PopupMenuItem(
  child: Consumer<YourProvider>(
    builder: (context, state, child) {
      return Switch(
        value: state.value,
        onChanged: (bool value) {
          state.handleValueChanged(value);
        },
      );
...

Upvotes: 5

kapil
kapil

Reputation: 121

you need state management, parent widget is not refreshed on that action, that is why state doesn't change, have a look at this https://stackoverflow.com/a/51778268/5180337 it will fix your issue

Upvotes: 1

Related Questions