Reputation: 712
I have a bottom navigation bar widget for my Flutter app. On tapping specific item it is navigating to another screen. However, I don't know how to update current index in this case so that selected tab gets highlighted. Here is my code:
BottomNavigationBar(
backgroundColor: const Color(0xffFF7B19),
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(
Icons.calendar_today_rounded,
size: lh / 25,
),
label: 'Events',
),
BottomNavigationBarItem(
icon: Icon(
Icons.people_alt_outlined,
size: lh / 25,
),
label: 'Councils',
),
],
currentIndex: 0,
selectedItemColor: Colors.grey[900],
unselectedItemColor: Colors.grey[50],
onTap: (int index) {
if (index == 0) {
Navigator.push(context,
MaterialPageRoute(builder: (context) => AllEventsScreen()));
} else {
Navigator.push(
context, MaterialPageRoute(builder: (context) => Councils()));
}
})
I have tried creating a variable _selectedIndex
for this which I was updating inside the function I have provided for onTap as shown:
currentIndex: _selectedIndex,
selectedItemColor: Colors.grey[900],
unselectedItemColor: Colors.grey[50],
onTap: (int index) {
if (index == 0) {
Navigator.push(context,
MaterialPageRoute(builder: (context) => AllEventsScreen()));
_selectedIndex = 0;
} else {
Navigator.push(
context, MaterialPageRoute(builder: (context) => Councils()));
_selectedIndex = 1;
}
But this doesn't seems to work. I couldn't figure out how to do this.
Upvotes: 4
Views: 3024
Reputation: 269
it's been 1 year, but i ran with the same situation, i've been trying to solve it , the main points are:
Create the bottom bar with screens
update the index accordingly
save the state of the index
Basic bottom Nav bar with design
```
final PageController _controller = PageController();
final int _currentIndex = 0;
final List<Widget> _screens = const [
Home(),
Screen2(),
Screen3()
];
void onTap(int index) {
_controller.jumpToPage(index);
}
@override
Widget build(BuildContext context) {
return Scaffold(
bottomNavigationBar: BottomNavigationBar(
type: BottomNavigationBarType.fixed,
backgroundColor: Colors.white,
selectedLabelStyle: const TextStyle(color: Colors.black),
selectedItemColor: Colors.yellow,
unselectedItemColor: Colors.black54,
showUnselectedLabels: true,
showSelectedLabels: true,
elevation: 3,
currentIndex: _currentIndex,
onTap: (index) {
_controller.jumpToPage(index);
setState(() {
_currentIndex = index;
});
},
items: [
BottomNavigationBarItem(
label: "Home"),
BottomNavigationBarItem(
label: "screen2"),
BottomNavigationBarItem(
label: "screen3"),
],
),
body: PageView(
physics: const NeverScrollableScrollPhysics(),
controller: _controller,
children: _screens,
),
);}
For saving the state of the current index, i wrapped a Stack with the PageView!
Stack(
children: [
PageView(
physics: const NeverScrollableScrollPhysics(),
controller: _controller,
children: _screens,
),
],
)
This is the trick, i hope it will work with you as well!
Upvotes: 0
Reputation: 3730
You could go with the first answer or you could go with TabBarView
return DefaultTabController(
length: 2,
child: Scaffold(
body: TabBarView(
children: [
Container(),
Container()
]
),
bottomNavigationBar: TabBar(
tabs: [
GestureDetector(
onTap: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) => AllEventsScreen()));
},
child: Tab(
icon: Icon(
Icons.calendar_today_rounded,
size: lh / 25,
),
text: 'Events',
),
),
GestureDetector(
onTap: () {
Navigator.push(
context, MaterialPageRoute(builder: (context) => Councils()));
},
child: Tab(
icon: Icon(
Icons.people_alt_outlined,
size: lh / 25,
),
text: 'Councils',
),
)]
)
),
);
Upvotes: 0
Reputation: 553
Use the _selectedIndex
with a PageView and set the onTap like this :
currentIndex: _selectedIndex,
selectedItemColor: Colors.grey[900],
unselectedItemColor: Colors.grey[50],
onTap: (int index) {
setState(()=>_selectedIndex=index);
}
Reading this article would be helpful
Edit: This is a full example
class MyHomePage extends StatefulWidget {
MyHomePage({
Key? key,
}) : super(key: key);
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _selectedIndex = 0;
late PageController _pageController;
@override
void initState() {
super.initState();
_pageController = PageController(
initialPage: _selectedIndex,
);
}
Widget build(BuildContext context) {
return Scaffold(
bottomNavigationBar: BottomNavigationBar(
currentIndex: _selectedIndex,
onTap: (index) {
setState(() {
_selectedIndex = index;
_pageController.animateToPage(index,
duration: Duration(milliseconds: 500), curve: Curves.ease);
});
},
items: [
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: "Home",
),
BottomNavigationBarItem(
icon: Icon(Icons.search),
label: "Search",
),
],
),
appBar: AppBar(
title: Text('Test App'),
),
body: PageView(
controller: _pageController,
onPageChanged: (index) {
setState(() {
_selectedIndex = index;
});
},
children: [
Container(
color: Colors.red,
child: Center(
child: Text("Home"),
),
),
Container(
color: Colors.green,
child: Center(
child: Text("Search"),
),
),
],
));
}
}
Upvotes: 1