V Nikoyan
V Nikoyan

Reputation: 1348

ChipSelect callback is not updating the UI. Flutter

I gave up trying to find the reason setState() is not running build method. I have a ChoiceChip which has a callback function. Debug showed me that I actually receive the selected chip at the callback but setState() is not updating the ui. I have spent all day trying to understand why setState() is not running the build() method. Here is my code

   class SocialStoryCategory extends StatefulWidget {
      final Function(String) onMenuItemPress;
      SocialStoryCategory({Key key, @required this.onMenuItemPress}) : sup er(key: key);

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

    class _SocialStoryCategoryState extends State<SocialStoryCategory> {
      int _value = 0;
      List<String> categoryList;
      @override
      Widget build(BuildContext context) {
        categoryList = [
          NoomeeLocalizations.of(context).trans('All'),
          NoomeeLocalizations.of(context).trans('Communication'),
          NoomeeLocalizations.of(context).trans('Behavioral'),
          NoomeeLocalizations.of(context).trans('ADL'),
          NoomeeLocalizations.of(context).trans('Other')
        ];

        return Wrap(
            spacing: 4,
            children: List<Widget>.generate(5, (int index) {
              return Theme(
                data: ThemeData.from(
                    colorScheme: ColorScheme.light(primary: Colors.white)),
                child: Container(
                  child: ChoiceChip(
                    elevation: 3,
                    selectedColor: Colors.lightBlueAccent,
                    label: Text(categoryList.elementAt(index)),
                    selected: _value == index,
                    onSelected: (bool selected) {
                      setState(() {
                        _value = selected ? index : null;

                        if (categoryList.elementAt(_value) == "All") {
                          widget.onMenuItemPress("");
                        } else {
                          widget.onMenuItemPress(categoryList.elementAt(_value));
                        }
                      });
                    },
                  ),
                ),
              );
            }).toList());
      }
    }

Here is the place where I get the callback

 class SocialStoriesHome extends StatefulWidget {
      @override
      _SocialStoriesHomeState createState() => _SocialStoriesHomeState();
    }

    class _SocialStoriesHomeState extends State<SocialStoriesHome>
        with TickerProviderStateMixin {
      String title;
      TabController _tabController;
      int _activeTabIndex = 0;
      String _defaultStoryCategory;

      _goToDetailsPage() {
        Navigator.of(context).pushNamed("parent/storyDetails");
      }


      @override
      void dispose() {
        _tabController.dispose();
        super.dispose();
      }

      @override
      void initState() {
        super.initState();
        _tabController = TabController(vsync: this, length: 2);
        _defaultStoryCategory = '';
      }

      @override
      Widget build(BuildContext context) {
        return BaseWidget<SocialStoryViewModel>(
          model: new SocialStoryViewModel(
            socialStoriesService: Provider.of(context),
          ),
          onModelReady: (model) =>
              model.fetchDefaultStoriesByCategory(_defaultStoryCategory),
          builder: (context, model, child) => DefaultTabController(
            length: 2,
            child: Scaffold(


              body: model.busy
                  ? Center(child: CircularProgressIndicator())
                  : Container(
                            child: Column(
                              children: <Widget>[
                                new SocialStoryCategory(
                                  onMenuItemPress: (selection) {
                                   setState(() {
                                      _defaultStoryCategory = selection;

                                    });
                                  },
                                ),

                                Expanded(
                                  child: ListView(
                                    children: getStories(model.socialStories),
                                  ),
                                ),
                              ],
                            ),
          ),
        );
      }
    }

    List<Widget> getStories(List<SocialStoryModel> storyList) {
      List<Widget> list = List<Widget>();
      for (int i = 0; i < storyList.length; i++) {
        list.add(Padding(
          padding: const EdgeInsets.all(8.0),
          child: Template(
              title: storyList[i].name,
              subTitle: storyList[i].categories,
              hadEditIcon: false),
        ));
      }
      return list;
    }

Upvotes: 1

Views: 434

Answers (1)

V Nikoyan
V Nikoyan

Reputation: 1348

Finally I have found the solution. I have simply replaced

new SocialStoryCategory(onMenuItemPress: (selection) {
                                   setState(() {
                                      _defaultStoryCategory = selection;

                                    });
                                  },
                                ),

to

 new SocialStoryCategory(
                              onMenuItemPress: (selection) {
                                 model.fetchDefaultStoriesByCategory(selection);
                              },
                            ),

my viewModel extend change notifier and build a child as consumer so I totally understand why it works. But I still do not understand why the previous version was not working. I will feel happy again only when you explain me the problem,

Upvotes: 1

Related Questions