简体   繁体   中英

How to switch BottomNavigationBar tabs Programmatically in flutter (and Navigate between pages)

I am using pretty new to flutter.So any good advice will be helpful to me.

I am creating an app which have three pages - one home page, one details page, and one Settings page. So in my code for home page, after submitting some data, the user will be taken to page two (ie. the details page)

I am using curved_navigation_bar [ https://pub.dev/packages/curved_navigation_bar ] package as my BottomNavigationBar .

HomeView.dart

import 'package:curved_navigation_bar/curved_navigation_bar.dart';
//necessary imports

class HomeView extends StatefulWidget {
  final GlobalKey globalKey;

  HomeView(this.globalKey);

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

class _HomeViewState extends State<HomeView> {
  @override
  Widget build(BuildContext context) {
    return Container(
      child: //SomeButton(
        onPressed: () => {
          final CurvedNavigationBar navigationBar = widget.globalKey.currentWidget;
          navigationBar.onTap(1);  //<-This is the line where user will be taken to page 2
        }
      ),
    );
  }
}

Now I have made a NavBar.dart file to manage navigation in my app.

NavBar.dart

import 'package:curved_navigation_bar/curved_navigation_bar.dart';
//necessary imports

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

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

class _NavBarState extends State<NavBar> {
  GlobalKey globalKey = new GlobalKey(debugLabel: 'btm_app_bar');
  ChatSessionDetails _chatSessionDetails = ChatSessionDetails();

  int _currentIndex;
  String _appBarTitle;

  List<Widget> pages = [];

  final PageStorageBucket bucket = PageStorageBucket();

  void initState() {
    super.initState();

    pages = [
      HomeView(globalKey),
      ChatView(key: PageStorageKey('ChatPage')),
      SettingsView()
    ];

    _currentIndex = 0;
    _appBarTitle = 'HomePage';
  }

  void changeTab(int index) {      //<-PageChange logic
    switch (index) {
      case 0:
        setState(
          () => {
            _appBarTitle = 'HomePage',
            _currentIndex = 0,
          },
        );
        break;
      case 1:
        if (_sessionDetails.file != null) {
          setState(
            () => {
              _appBarTitle = //some title,
              _currentIndex = 1
            },
          );
        } else {
          ScaffoldMessenger.of(context).showSnackBar(SnackBar(
            content: Text('You haven\'t opened a session yet'),
            behavior: SnackBarBehavior.floating,
          ));
        }
        break;
      case 2:
        setState(
          () => {
            _appBarTitle = 'Settings',
            _currentIndex = 2,
          },
        );
        break;
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(_appBarTitle),
      ),
      body: PageStorage(
        child: pages[_currentIndex],
        bucket: bucket,
      ),
      extendBody: true,
      bottomNavigationBar: CurvedNavigationBar(
        key: globalKey,        items: <Widget>[
          Icon(Icons.home_rounded, size: 30, color: Colors.grey[600]),
          Icon(CustomIcons.whatsapp, size: 30, color: Colors.grey[600]),
          Icon(Icons.settings_rounded, size: 30, color: Colors.grey[600]),
        ],
        onTap: (index) {
          changeTab(index); //Handle button tap
        },
      ),
    );
  }
}

The whole navigation thing goes pretty fine, but when I call that changeTab() function programmatically, (not by clicking on the bottom navigation tabs ) things get weird.

Below is link to the gif MyApp

The tab should change as I didn't changed the state as _sessionDetails.file != null is false . How can I avoid this?

in changeTab you need to use the key to change page:

globalKey.currentState.setPage(1);

[UPDATED]

Official way from author:

Change page programmatically

  //State class
  int _page = 0;
  GlobalKey _bottomNavigationKey = GlobalKey();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        bottomNavigationBar: CurvedNavigationBar(
          key: _bottomNavigationKey,
          items: <Widget>[
            Icon(Icons.add, size: 30),
            Icon(Icons.list, size: 30),
            Icon(Icons.compare_arrows, size: 30),
          ],
          onTap: (index) {
            setState(() {
              _page = index;
            });
          },
        ),
        body: Container(
          color: Colors.blueAccent,
          child: Center(
            child: Column(
              children: <Widget>[
                Text(_page.toString(), textScaleFactor: 10.0),
                RaisedButton(
                  child: Text('Go To Page of index 1'),
                  onPressed: () {
                    //Page change using state does the same as clicking index 1 navigation button
                    final CurvedNavigationBarState navBarState =
                        _bottomNavigationKey.currentState;
                    navBarState.setPage(1);
                  },
                )
              ],
            ),
          ),
        ));
  }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM