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);
},
)
],
),
),
));
}