1

I have a BottomNavigationBar in a stateless widget. I'm using ViewModelProvider to control the tab change when onTap event. I have no issue navigating using the BottomNavigationBar, but I was unable to control the navigation bar from inside the body. I'm using the following method, I have tried streambuilder to control the navigation, but streambuilder will dispose of the content when navigate to another tab which is not what I wanted. I am not able to click on button in Profile Page and navigate to Home page.

Below are my widget for BottomNavigationBar.

class BottomNavigationView extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ViewModelProvider<BottomNavigationViewModel>.withConsumer(
      viewModel: BottomNavigationViewModel(),
      builder: (context, model, child) => Scaffold(
        primary: false,
        body: IndexedStack(
          children: <Widget>[
            BrowseView(),
            HomeView(),
            ProfileView(),
          ],
          index: model.currentIndex,
        ),
        bottomNavigationBar: BottomNavigationBar(
          type: BottomNavigationBarType.fixed,
          backgroundColor: Colors.white,
          currentIndex: model.currentIndex,
          onTap: model.changeView,
          items: [
            BottomNavigationBarItem(
              icon: new Icon(Icons.search),
              title: SizedBox.shrink(),
            ),
            BottomNavigationBarItem(
              icon: new Icon(Icons.home),
              title: SizedBox.shrink(),
            ),
            BottomNavigationBarItem(
              icon: new Icon(WineIcon.person),
              title: SizedBox.shrink(),
            ),
          ],
        ),
      ),
    );
  }
}

Navigation Bar View Model

class BottomNavigationViewModel extends ChangeNotifier {
  int _currentIndex = 2;
  int get currentIndex => _currentIndex;

  void changeView(int index) {
    _currentIndex = index;
    notifyListeners();
  }
}

Profile View & Profile View Model

class ProfileView extends StatelessWidget {
  const ProfileView ({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return ViewModelProvider<ProfileViewModel>.withConsumer(
      viewModel: ProfileViewModel(),
      builder: (context, model, child) => Scaffold(
        body: Center(
          child: RaisedButton(
             onPressed: ()=> model.goHome(),
             child:Text('Go to Home'),
          ),
        )
      ),
    );
  }
}

class ProfileViewModel extends ChangeNotifier {
  final BottomNavigationViewModel _bottomNavigationBar =
      locator<BottomNavigationViewModel>();

  void goHome() {
    _bottomNavigationBar.changeView(1);
  }
}
Chun Lin
  • 11
  • 4

1 Answers1

0

Don't fully understand what you mean by "unable to control the navigation bar from inside the body". but I think you mean by the btmnav is gone when you navigate within each page? You are halfway there using Indexstack to keep the state of the pages inside. Didn't use a streambuilder for my part but for navigator of each page, create a global key to use.

Navigator(
          key: 1 key for each tab here,

          onGenerateRoute: (settings) => MaterialPageRoute(
            settings: settings,
            builder: (context) => page,
          ), // this will generate your pages

if you want to replace the whole page then

Navigator.of(context,rootNavigator: true).push(MaterialPageRoute(builder: (context) =>anotherpage)

else just set rootNavigator to false

Solly
  • 41
  • 5
  • 2
    What i meant was i like to navigate the bottom navigation bar without tabbing on the bar itself. I like to navigate it by a button inside a page. – Chun Lin Apr 10 '20 at 05:19