enggPS
enggPS

Reputation: 712

How should I change currentIndex property of BottomNavigationBar on Navigating to another screen?

I have a bottom navigation bar widget for my Flutter app. On tapping specific item it is navigating to another screen. However, I don't know how to update current index in this case so that selected tab gets highlighted. Here is my code:

        BottomNavigationBar(
          backgroundColor: const Color(0xffFF7B19),
          items: <BottomNavigationBarItem>[
            BottomNavigationBarItem(
              icon: Icon(
                Icons.calendar_today_rounded,
                size: lh / 25,
              ),
              label: 'Events',
            ),
            BottomNavigationBarItem(
              icon: Icon(
                Icons.people_alt_outlined,
                size: lh / 25,
              ),
              label: 'Councils',
            ),
          ],
          currentIndex: 0,
          selectedItemColor: Colors.grey[900],
          unselectedItemColor: Colors.grey[50],
          onTap: (int index) {
            if (index == 0) {
              Navigator.push(context,
                  MaterialPageRoute(builder: (context) => AllEventsScreen()));
            } else {
              Navigator.push(
                  context, MaterialPageRoute(builder: (context) => Councils()));
            }
          })

Here is the output

I have tried creating a variable _selectedIndex for this which I was updating inside the function I have provided for onTap as shown:

          currentIndex: _selectedIndex,
          selectedItemColor: Colors.grey[900],
          unselectedItemColor: Colors.grey[50],
          onTap: (int index) {
            if (index == 0) {
              Navigator.push(context,
                  MaterialPageRoute(builder: (context) => AllEventsScreen()));
              _selectedIndex = 0;
            } else {
              Navigator.push(
                  context, MaterialPageRoute(builder: (context) => Councils()));
              _selectedIndex = 1;
            }

But this doesn't seems to work. I couldn't figure out how to do this.

Upvotes: 4

Views: 3024

Answers (3)

Hanaa
Hanaa

Reputation: 269

it's been 1 year, but i ran with the same situation, i've been trying to solve it , the main points are:

  1. Create the bottom bar with screens

  2. update the index accordingly

  3. save the state of the index

Basic bottom Nav bar with design

```
  final PageController _controller = PageController();
  final int _currentIndex = 0;

  final List<Widget> _screens = const [
    Home(),
    Screen2(),
    Screen3()
  ];
  
  void onTap(int index) {
    _controller.jumpToPage(index);
  }

  @override
  Widget build(BuildContext context) {
     return Scaffold(
       bottomNavigationBar: BottomNavigationBar(
       type: BottomNavigationBarType.fixed,
       backgroundColor: Colors.white,
       selectedLabelStyle: const TextStyle(color: Colors.black),
       selectedItemColor: Colors.yellow,
       unselectedItemColor: Colors.black54,
       showUnselectedLabels: true,
       showSelectedLabels: true,
       elevation: 3,
       currentIndex: _currentIndex,
       onTap: (index) {
        _controller.jumpToPage(index);
        setState(() {
         _currentIndex = index;
        });
       },
       items: [
         BottomNavigationBarItem(
          label: "Home"),
         BottomNavigationBarItem(
          label: "screen2"),
         BottomNavigationBarItem(
          label: "screen3"),
       ],
      ),
    body: PageView(
     physics: const NeverScrollableScrollPhysics(),
     controller: _controller,
     children: _screens,
   ),
);}

For saving the state of the current index, i wrapped a Stack with the PageView!

  Stack(
        children: [
          PageView(
            physics: const NeverScrollableScrollPhysics(),
            controller: _controller,
            children: _screens,
          ),
        ],
      )

This is the trick, i hope it will work with you as well!

Upvotes: 0

Rohith Nambiar
Rohith Nambiar

Reputation: 3730

You could go with the first answer or you could go with TabBarView

return DefaultTabController(
  length: 2,
  child: Scaffold(
    body: TabBarView(
      children: [
        Container(),
        Container()
      ]
    ),
    bottomNavigationBar: TabBar(
      tabs: [
          GestureDetector(
            onTap: () {
              Navigator.push(context,
                MaterialPageRoute(builder: (context) => AllEventsScreen()));
            },
            child: Tab(
              icon: Icon(
                Icons.calendar_today_rounded,
                size: lh / 25,
              ),
              text: 'Events',
            ),
          ),
          GestureDetector(
            onTap: () {
              Navigator.push(
                context, MaterialPageRoute(builder: (context) => Councils()));
            },
            child: Tab(
              icon: Icon(
                Icons.people_alt_outlined,
                size: lh / 25,
              ),
              text: 'Councils',
            ),
          )]
    )
  ),
);

Upvotes: 0

Youssef Elmoumen
Youssef Elmoumen

Reputation: 553

Use the _selectedIndex with a PageView and set the onTap like this :

          currentIndex: _selectedIndex,
          selectedItemColor: Colors.grey[900],
          unselectedItemColor: Colors.grey[50],
          onTap: (int index) {
              setState(()=>_selectedIndex=index);
            }

Reading this article would be helpful

Edit: This is a full example

class MyHomePage extends StatefulWidget {
  MyHomePage({
    Key? key,
  }) : super(key: key);

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _selectedIndex = 0;
  late PageController _pageController;
  @override
  void initState() {
    super.initState();
    _pageController = PageController(
      initialPage: _selectedIndex,
    );
  }

  Widget build(BuildContext context) {
    return Scaffold(
        bottomNavigationBar: BottomNavigationBar(
          currentIndex: _selectedIndex,
          onTap: (index) {
            setState(() {
              _selectedIndex = index;
              _pageController.animateToPage(index,
                  duration: Duration(milliseconds: 500), curve: Curves.ease);
            });
          },
          items: [
            BottomNavigationBarItem(
              icon: Icon(Icons.home),
              label: "Home",
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.search),
              label: "Search",
            ),
          ],
        ),
        appBar: AppBar(
          title: Text('Test App'),
        ),
        body: PageView(
          controller: _pageController,
          onPageChanged: (index) {
            setState(() {
              _selectedIndex = index;
            });
          },
          children: [
            Container(
              color: Colors.red,
              child: Center(
                child: Text("Home"),
              ),
            ),
            Container(
              color: Colors.green,
              child: Center(
                child: Text("Search"),
              ),
            ),
          ],
        ));
  }
}

Upvotes: 1

Related Questions