0

I am trying to display the BottomNavigationBar on every View I have, it's working but this is a "dumb" way to do that...

I have a custom BottomNavigationBar which I am inserting in every View.

var selectedIndex = 0;
class CustomBottombar extends StatefulWidget {
  CustomBottombar({Key key}) : super(key: key);
  @override
  _CustomBottombarState createState() => _CustomBottombarState();
}

class _CustomBottombarState extends State<CustomBottombar> {
  List _viewList = [FirstView(), SecondView()];
  @override
  Widget build(BuildContext context) {
    return BottomNavigationBar(
      currentIndex: selectedIndex,
      onTap: _onItemTapped,
       items: _items,
    );
  }

  void _onItemTapped(int index) {
    setState(() {
      selectedIndex = index;
      Navigator.of(context).popUntil((route) => route.isFirst
      );
      Navigator.pushReplacement(
              context,
              MaterialPageRoute(builder: (context) => _viewList[index]),
            );
    });
  }
  final _items = [
BottomNavigationBarItem(
            icon: Icon(
              Icons.refresh,
              color: Color(0xFFACACAC),
              size: 35,
            ),
            title: Text("first")),
BottomNavigationBarItem(
          icon: Icon(
            Icons.phone,
            color: Color(0xFFACACAC),
            size: 35,
          ),
          title: Text("second"),
        ),
BottomNavigationBarItem(
          icon: Icon(
            Icons.add_shopping_cart,
            color: Color(0xFFACACAC),
            size: 35,
          ),
          title: Text("thrid"),
        ),

]; }

in the _onItemTapped function I pop everything from the "Navigationstack" and then I am displaying the Screen that is in my Items.

in my FirstView() I have then this code

class FirstView extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: CustomAppBar(""),
      bottomNavigationBar: CustomBottombar(),
      endDrawer: CustomDrawer(),
      body: Center(
        child: RaisedButton(
          onPressed: () {
            Navigator.push(
              context,
              MaterialPageRoute(builder: (context) => ContactView()),
            );
          },
          child: Text('First'),
        ),
      ),
    );
  }
}

Now I want to move to "ContactView" which is not an Item in the BottomNavigationBar

class ContactState extends State<ContactView> {
@override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: CustomAppBar("title"),
      endDrawer: CustomDrawer(),
      bottomNavigationBar: CustomBottombar(),
      body: SafeArea(
          bottom: true,
          child: SingleChildScrollView(
            child: Container(child: Text("Contact"),),
          )),
    );
  }
}

I'll also have a lot of other views which are not in the items array but I want to display the BottomNavigationBar on. My Issue is really this function.

void _onItemTapped(int index) {
        setState(() {
          selectedIndex = index;
          Navigator.of(context).popUntil((route) => route.isFirst
          );
          Navigator.pushReplacement(
                  context,
                  MaterialPageRoute(builder: (context) => _viewList[index]),
                );
        });
      }

because here I'm deleting the navigation history to display the View which is in the Items Array. Is there a standard way to do this, Hopefully, someone can help.

EDIT: For clarification: I have like 10 Screens. Only 3 of those are navigatiable via BottomNavigationBar, Let's say the first 3 of those 10. now I want to Navigate to Screen4 from Screen1. The navigationbar disappears on screen4. I want Want to keep the Navigationbar on all Screens.

Edit 2

@Dhaval Kansara answer worked for me but I got a new Problem. I have an enddrawer, before the fix it was above the BottomNavigationBar now the BottomNavigationBar is above.

enter image description here

but I want it like this

enter image description here

nani
  • 183
  • 2
  • 15

1 Answers1

2

Use CupertinoTabBar as shown below for the static BottomNavigationBar.

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:mqttdemo/Screen2.dart';
import 'package:mqttdemo/Screen3.dart';

import 'Screen1.dart';

class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
  int _currentIndex;
  List<Widget> _children;

  @override
  void initState() {
    _currentIndex = 0;
    _children = [
      Screen1(),
      Screen2(),
      Screen3(),
    ];
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return CupertinoTabScaffold(
      tabBar: CupertinoTabBar(
        currentIndex: _currentIndex,
        onTap: onTabTapped,
        items: [
          BottomNavigationBarItem(
            icon: Icon(Icons.home),
            title: Text("Screen 1"),
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.home),
            title: Text("Screen 2"),
          ),
          BottomNavigationBarItem(
              icon: Icon(Icons.home), title: Text("Screen 3")),
        ],

      ),
        tabBuilder: (BuildContext context, int index) {
          return CupertinoTabView(
            builder: (BuildContext context) {
              return SafeArea(
                top: false,
                bottom: false,
                child: CupertinoApp(
                  home: CupertinoPageScaffold(
                    resizeToAvoidBottomInset: false,
                    child: _children[_currentIndex],
                  ),
                ),
              );
            },
          );
        }
    );
  }

  void onTabTapped(int index) {
    setState(() {
      _currentIndex = index;
    });
  }
}

Navigate to screen4 from Screen3 as shown below:

    class Screen3 extends StatefulWidget {
      @override
      _Screen3State createState() => _Screen3State();
    }

    class _Screen3State extends State<Screen3> {
      @override
      Widget build(BuildContext context) {
        return Container(
          color: Colors.black,
          child: Center(
            child: RaisedButton(
              child: Text("Click me"),
              onPressed: () {
                Navigator.of(context, rootNavigator: false).push(MaterialPageRoute(
                    builder: (context) => Screen4(), maintainState: false));
              },
            ),
          ),
        );
      }

}
Dhaval Kansara
  • 3,478
  • 5
  • 22
  • 50
  • Yeah but in my case I have like 10 Screens but only 3 of them are BottomNavigationBarItems. but I need the BottomNavigationBar in every Screen. Like the first 3 are Items in the NavigationBar but when navigating to Screen >3 the NavigationBar should stay. – nani May 04 '20 at 14:36
  • @nani what is your plan to navigate on the fourth screen? – Dhaval Kansara May 04 '20 at 19:29
  • via Button click from firstView to contact. Navigator.push( context, MaterialPageRoute(builder: (context) => ContactView()), ); – nani May 05 '20 at 07:55
  • Means For the first 3 screes you want to operate using `BottomNavigationBar` and after that from those screes if User navigates to any other screen then still you want `BottomNavigationBar` visible on those screens too right? – Dhaval Kansara May 05 '20 at 08:30
  • @nani Did you tried this solution for your example? I think this will work in you case. – Dhaval Kansara May 05 '20 at 08:36
  • Honestly no, will do that and then give you a reply. – nani May 05 '20 at 08:51
  • Didn't work, l Only have 3 BottomNavigationBarItems, my Screen 4 will not be part of the BottomNavigation. – nani May 05 '20 at 09:05
  • @nani I have updated my answer try this. I have created a demo for the same and it's working for me. – Dhaval Kansara May 05 '20 at 11:31
  • ok this worked. But it created a new "bug" with my drawer maybe you can help me there? I ll update the question, if not then no prob. – nani May 05 '20 at 12:32
  • @nani sorry No idea about that – Dhaval Kansara May 05 '20 at 13:19