2

Basically, I have a main widget that has a this._bottomNavigationBar and when the screen will change, I pass it to the new screen. Then, each screen has its own Scaffold and AppBar.

Sounds perfectly, but it's not working properly.

When I click to change the selected option, it changes the screen, but the selected icon keeps the same. If I print the this.currentIndex, it changes the index normally. Something that I was not expecting to happen, because when I declare the this._bottomNavigationBar, the currentIndex property is defined like that: currentIndex: this.currentIndex, so if the icon isn't changing, then the variable won't either.

So, I realized that I probably forgive to use the setState() method on the onTap, but it wasn't the case.

I just don't know why this is happening. I think it's something about the setState "scope", maybe? I'll leave my code below to illustrate this better.

home.dart

import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'landing.dart';

const List<BottomNavigationBarItem> homeScreenNavbarItems = [
  BottomNavigationBarItem(
    icon: Icon(FontAwesomeIcons.home),
    title: Text(''),
  ),
  BottomNavigationBarItem(
    icon: Icon(Icons.search),
    title: Text(''),
  ),
  BottomNavigationBarItem(
    icon: Icon(Icons.bookmark),
    title: Text(''),
  ),
  BottomNavigationBarItem(
    icon: Icon(Icons.person),
    title: Text(''),
  ),
];

class Home extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return _HomeState();
  }
}

class _HomeState extends State<Home> {
  int currentIndex = 1;
  BottomNavigationBar _bottomNavigationBar;
  List homeScreens;

  void onNavbarTapped(int index) {
    setState(() {
      this.currentIndex = index;
    });
  }

  @override
  void initState() {
    this._bottomNavigationBar = BottomNavigationBar(
      showSelectedLabels: false,
      showUnselectedLabels: false,
      selectedItemColor: Color(0xFF000000),
      unselectedItemColor: Color(0xFFb3b3b3),
      currentIndex: this.currentIndex,
      items: homeScreenNavbarItems,
      onTap: this.onNavbarTapped,
    );

    this.homeScreens = [
      LandingScreen(this._bottomNavigationBar),
      Scaffold(
        bottomNavigationBar: this._bottomNavigationBar,
      )
    ];
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    print(this.currentIndex);
    return this.homeScreens.elementAt(this.currentIndex);
  }
}

landing.dart

import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';

class LandingScreen extends StatefulWidget {
  final BottomNavigationBar _bottomNavigationBar;

  LandingScreen(this._bottomNavigationBar);

  @override
  State<StatefulWidget> createState() {
    return _LandingScreenState();
  }
}

class _LandingScreenState extends State<LandingScreen> {
  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
      length: 3,
      child: Scaffold(
        appBar: AppBar(
          title: Text('a'),
          bottom: TabBar(
            tabs: [
              Tab(icon: Icon(Icons.directions_car)),
              Tab(icon: Icon(Icons.directions_transit)),
              Tab(icon: Icon(Icons.directions_bike)),
            ],
          ),
        ),
        body: TabBarView(
          children: [
            Icon(Icons.directions_car),
            Icon(Icons.directions_transit),
            Icon(Icons.directions_bike),
          ],
        ),
        bottomNavigationBar: widget._bottomNavigationBar,
      ),
    );
  }
}

The main.dart file is simply calling the Home widget, so I didn't place it here.

Edit

I removed all the content of the initState method and placed then into the Widget build method, worked, but I don't know exactly why...
Enzo Dtz
  • 361
  • 1
  • 16

1 Answers1

0

The issue here is that the BottomNavigationBar is configured in initState. When currentIndex has been updated after calling setState, the properties aren't updated because it's inside initState instead of Widget build.

Omatt
  • 8,564
  • 2
  • 42
  • 144