BottomNavigationBar with Navigator

53 Views Asked by At

I just want to know, can I make bottomnavigationbar reusable, because what i saw in the other similar problem is just they use list of screen and then using scaffold that it makes cannot be reusable for my cases, and I just want to know is this even possible?

import 'package:conditional/HistoryScreen.dart';
import 'package:conditional/HomeScreen.dart';
import 'package:flutter/material.dart';

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

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


class _NavBar extends State<NavBar>{
  int currentIndex = 0;

  @override
  Widget build(BuildContext context){
    return BottomNavigationBar(
      currentIndex: currentIndex,
      onTap: (index){
        setState(() {
          currentIndex = index;
        });

        switch(index){
          case 0:
            Navigator.push(context, MaterialPageRoute(builder: (context) => HomeScreen()));
            break;

          case 1:
            Navigator.push(context, MaterialPageRoute(builder: (context) => HistoryScreen()), );
            break;
        }
      },
      items: [
        BottomNavigationBarItem(
          icon: Icon(Icons.home),
          activeIcon: Icon(Icons.home, color: currentIndex == 0 ? Colors.red : Colors.grey),
          label: "Home"),

        BottomNavigationBarItem(
          icon:Icon(Icons.history),
          activeIcon: Icon(Icons.history, color: currentIndex == 1 ? Colors.red : Colors.grey),
          label: "History" )
      ],
      selectedItemColor: Colors.red,
    );
  }
}

import 'package:conditional/NavBar.dart';
import 'package:flutter/material.dart';

class HomeScreen extends StatelessWidget{
  HomeScreen({Key? key}):super(key: key);

  @override
  Widget build(BuildContext context){
    return Scaffold(
      body: Center(child: Text("This is Homescreen"),),
      bottomNavigationBar: NavBar(),
    );
  }
}
import 'package:conditional/NavBar.dart';
import 'package:flutter/material.dart';

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

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

class _HistoryScreen extends State<HistoryScreen>{

  @override
  Widget build(BuildContext context){
    return Scaffold(
      body: Text("This is History Screen"),
      bottomNavigationBar: NavBar(),
    );
  }
}

the main problem is was, if I clicked the history button, the home button still red and I don't event know where's the problem, But the navigator is working correctly as intended just the Color when its clicked, can you guys help me?

3

There are 3 best solutions below

0
Lorito Tiago On

You can create a reusable BottomNavigationBar in Flutter by encapsulating it within a separate widget.

import 'package:flutter/material.dart';


class ReusableBottomNavigationBar extends StatelessWidget {
  final int currentIndex;
  final Function(int) onTap;

  ReusableBottomNavigationBar({
    @required this.currentIndex,
    @required this.onTap,
  });

  @override
  Widget build(BuildContext context) {
    return BottomNavigationBar(
      currentIndex: currentIndex,
      onTap: onTap,
      items: [
        BottomNavigationBarItem(
          icon: Icon(Icons.home),
          label: 'Home',
        ),
        BottomNavigationBarItem(
          icon: Icon(Icons.person),
          label: 'Profile',
        ),
      ],
    );
  }
}

Then, you can use this ReusableBottomNavigationBar widget in any screen where you want to display a bottom navigation bar. Here's an example:

import 'package:flutter/material.dart';
import 'package:your_app/reusable_bottom_navigation_bar.dart';

class MyScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('My Screen'),
      ),
      body: Center(
        child: Text('This is my screen content'),
      ),
      bottomNavigationBar: ReusableBottomNavigationBar(
        currentIndex: 0,
        onTap: (index) {
          // Handle bottom navigation bar item taps
        },
      ),
    );
  }
}
0
Chalwe19 On

To achieve what you want, you can use the IndexedStack widget.

Your code will look like this:

class AppIndex extends StatefulWidget {
  const AppIndex({super.key});

  @override
  State<AppIndex> createState() => _AppIndexState();
}

class _AppIndexState extends State<AppIndex> {
  //create a list of your pages
  List<Widget> pages = [
    HomeScreen(),
    HistoryScreen(),
  ];

  int currentIndex = 0;

  //create a function to increment tab
  void incrementTab(index) {
    setState(() {
      currentIndex = index;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      //use an index stacked widget
      body: IndexedStack(
        index: currentIndex,
        children: pages,
      ),
      // your bottomNavigationBar would look like this
      bottomNavigationBar: BottomNavigationBar(
      currentIndex: currentIndex,
      onTap: incrementTab,
      items: [
        BottomNavigationBarItem(
          icon: Icon(Icons.home),
          activeIcon: Icon(Icons.home, color: currentIndex == 0 ? Colors.red : Colors.grey),
          label: "Home"),

        BottomNavigationBarItem(
          icon:Icon(Icons.history),
          activeIcon: Icon(Icons.history, color: currentIndex == 1 ? Colors.red : Colors.grey),
          label: "History" )
      ],
      selectedItemColor: Colors.red,
    )
    );
  }
}
0
Mehmet Güler On

You should use BottomAppBar widget

import 'package:flutter/material.dart';

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

  @override
  State<ItemDetails> createState() => _ItemDetailsState();
}

class _ItemDetailsState extends State<ItemDetails> {
  List bodyWidgets = [
    const Text(""),
    Container(),
  ];

  final int _currentIndex = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Item detail"),
      ),
      bottomNavigationBar: BottomAppBar(
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: [
            IconButton(
              onPressed: () async {
                //// Handle bottom navigation bar item taps
              },
              icon: const Icon(
                Icons.add,
                color: Colors.blue,
              ),
            ),
            IconButton(
              onPressed: () async {
                //// Handle bottom navigation bar item taps
              },
              icon: const Icon(
                Icons.accessibility_new,
                color: Colors.blue,
              ),
            ),
          ],
        ),
      ),
      body: bodyWidgets[_currentIndex],
    );
  }
}