Search code examples
fluttersetstate

Flutter - setState only updating after the second click and it renders the old value


I am trying to update the appbar text when the user clicks on a bottomNavigationBar item which also renders the body through a function called chooseTab(). I've placed the appBarText in the switch cases within the chooseTab() function but the setState doesn't update the appBar text until the second click. Even if it renders it renders the previous value of the appBar text. The body renders without any issues.

class HomeScreen extends StatefulWidget {
  static const String id = 'home_screen';

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

class _HomeScreenState extends State<HomeScreen> {
  String _appBarText = 'Dashboard';
  int _tabIndex = 0;
  GlobalKey _bottomNavigationKey = GlobalKey();

  chooseTab() {
    switch (this._tabIndex) {
      case 0:
        _appBarText = 'Dashboard';
        return new DashboardScreen();
        break;

      case 1:
        _appBarText = 'Cards';

        return new CardScreen();
        break;

      case 2:
        _appBarText = 'Receipts';

        return new ReceiptsScreen();
        break;

      case 3:
        _appBarText = 'Settings';

        return new SettingsScreen();
        break;
    }
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: kBackground,
      child: Scaffold(
        backgroundColor: Colors.transparent,
        appBar: AppBar(
          title: Text(
            _appBarText,
          ),
        ),
        body: chooseTab(),
        bottomNavigationBar: CurvedNavigationBar(
          key: _bottomNavigationKey,
          index: _tabIndex,
          height: 70.0,
          items: <Widget>[
            Icon(Icons.home, size: 25),
            Icon(Icons.credit_card, size: 25),
            Icon(Icons.receipt, size: 25),
            Icon(Icons.person, size: 25),
          ],
          onTap: (int tappedIndex) {
            setState(() {
              this._tabIndex = tappedIndex;
            });
          },
          color: Colors.grey[900],
          buttonBackgroundColor: Colors.grey[900],
          backgroundColor: Colors.transparent,
          animationCurve: Curves.easeInOut,
          animationDuration: Duration(milliseconds: 600),
        ),
      ),
    );
  }
}

Solution

  • it's because when you fire setState your widget tree rerender, but your switch case set _appBarText after AppBar shows and its time to show body content

    you can make a list of your titles like this:

    List<String> titles = [
       'Dashboard',
       'Cards',
       'Receipts',
       'Settings'
    ];
    

    and then your appBar should be like this:

    appBar: AppBar(
        title: Text(
            titles[_tabIndex],
        ),
    ),
    

    and try not using this keyword :)