How to update state from static method in Flutter?

3,338

This line will help you get the instance of the Widget State object you need.

All you need access to is the current context object:

  _HomeState stateObject = context.findAncestorStateOfType<_HomeState>();

  stateObject.setState(() {
     _tabIndex = index;
  });

For this to work, ensure that the context you use to access the State Object is from a child widget of the State object you are trying to find.

Share:
3,338
asmodeoux
Author by

asmodeoux

Updated on December 12, 2022

Comments

  • asmodeoux
    asmodeoux over 1 year

    I have a bottom nav bar that uses this code to switch widgets:

        void _onItemTapped(int index) {
        setState(() {
          selectedIndexGlobal = index;
          print(index);
        });
      }
    

    And shows the needed widgets in body:

    body: SafeArea(
        child: new LayoutBuilder(
              builder: (BuildContext context, BoxConstraints constraints) {
                Container con = Container(
                    child: _widgetOptions.elementAt(selectedIndexGlobal)
                );
                return con;
              }
          ))
    

    I also have a GridView with static children list loaded from Firebase, and tried to apply a GestureDetector to it, to change selectedIndex and update screen state:

    static getExpenseItems(AsyncSnapshot<QuerySnapshot> snapshot, BuildContext context) {
        try {
          snapshot.data.documents.sort((a, b) =>
              a.data["order"].compareTo(b.data["order"]));
        } on NoSuchMethodError {}
    
        return snapshot.data.documents
            .map((doc) =>
        new GestureDetector(
            behavior: HitTestBehavior.translucent,
            onTap: () {
            catName = doc["catName"];
            setState(() {
              selectedIndexGlobal = 4;
            });
            },
            child: new Container(
                child: Container(
                        padding: EdgeInsets.only(top: 15, left: 10, bottom: 15),
                        decoration: new BoxDecoration(
                            border: new Border.all(color: Colors.grey[200],
                            width: 0.8)),
                        child: Align(
                          alignment: Alignment.centerLeft,
                          child: Text(doc["name"],
                              style: TextStyle(fontSize: categoriesFont),
                              textAlign: TextAlign.center),
                        )
                    )
            )
    
        )
        ).toList();
      }
    

    But setState can't be called from a static method, as well as GridView.count doesn't let me use non-static widgets as child. What should I do then to update state on click?

    • nonybrighto
      nonybrighto almost 5 years
      Why not remove the static keyword?
    • Martin Niederl
      Martin Niederl almost 5 years
      You might be able to pass a "callback" to the static function that updates the state from the outside.
    • asmodeoux
      asmodeoux almost 5 years
      @nonybrighto GridView only accepts a static children list
    • asmodeoux
      asmodeoux almost 5 years
      @Martin Niederl can you give an example, please?
    • Jaydeep chatrola
      Jaydeep chatrola over 4 years
      i have same issue any idea?