I'm using the BottomNavigationBar the BottomNavigationBarItem widget to switch through pages within one scaffold. My problem:
I'm also using a Drawer to give navigation options. I was able to use the same list of pages I use with the bottom navigation bar in the drawer. That works. But: I now want to use the drawer to offer more pages than in the bottom bar and as soon as I want to set the index to those pages, the BottomNavigationBar throws an error:
'package:flutter/src/material/bottom_navigation_bar.dart': Failed assertion: line 192 pos 15: '0 <= currentIndex && currentIndex < items.length': is not true.
What seems to happen is that the BottomNavigationBar is keeping me from using more pages than connected to the Bottom Bar. Is there anay way around this? I don't want more than 4 symbols in the bottom bar, but I want 5 pages; and if possible all of them in the same Scaffold. Thanks!
CodePudding user response:
For making this you need to manage variables logically. Here is a complete example.
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
onGenerateRoute: (settings) {
switch (settings.name) {
case HomePage.route:
return MaterialPageRoute(
builder: (context) => Scaffold(
body: Container(
color: Colors.amber,
child: const Text("home"),
),
),
settings: const RouteSettings(name: HomePage.route));
}
},
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
static const String route = "/home";
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
int _pageIndex = 0;
int _drawerIndex = 0;
List<int> screenStack = [0];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("page $_pageIndex"),
),
body: SafeArea(
child: WillPopScope(
onWillPop: () async {
if (screenStack.length > 1) {
setState(() {
screenStack.removeLast();
_pageIndex = screenStack[screenStack.length - 1];
});
return false;
}
return true;
},
child: IndexedStack(
index: (_drawerIndex < _pageIndex) ? _pageIndex : _drawerIndex,
children: <Widget>[
Container(
color: Colors.amber,
child: Center(
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const Scaffold(
body: Center(
child: Text("DetailsPage"),
),
)));
},
child: const Text("navigate"),
),
const Text('Home'),
],
),
),
),
Container(
color: Colors.green,
child: const Center(child: Text('Business')),
),
Container(
color: Colors.amber,
child: const Center(child: Text('Technology')),
),
Container(
color: Colors.blueAccent,
child: const Center(child: Text('Education')),
),
Container(
color: Colors.deepOrange,
child: const Center(child: Text('Others')),
),
],
),
),
),
drawer: Drawer(
child: Padding(
padding: const EdgeInsets.all(18.0),
child: Column(
children: [
ListTile(
onTap: () {
Navigator.of(context).pop();
setState(
() {
_pageIndex = 0;
_drawerIndex = _pageIndex;
if (_pageIndex == 0) {
screenStack = [0];
} else if (!screenStack.contains(_pageIndex)) {
screenStack.add(_pageIndex);
}
},
);
},
title: const Text("Home"),
),
ListTile(
onTap: () {
Navigator.of(context).pop();
setState(
() {
_pageIndex = 1;
_drawerIndex = _pageIndex;
if (_pageIndex == 0) {
screenStack = [0];
} else if (!screenStack.contains(_pageIndex)) {
screenStack.add(_pageIndex);
}
},
);
},
title: const Text("Business"),
),
ListTile(
onTap: () {
Navigator.of(context).pop();
setState(
() {
_pageIndex = 2;
_drawerIndex = _pageIndex;
if (_pageIndex == 0) {
screenStack = [0];
} else if (!screenStack.contains(_pageIndex)) {
screenStack.add(_pageIndex);
}
},
);
},
title: const Text("Technology"),
),
ListTile(
onTap: () {
Navigator.of(context).pop();
setState(
() {
_pageIndex = 3;
_drawerIndex = _pageIndex;
if (_pageIndex == 0) {
screenStack = [0];
} else if (!screenStack.contains(_pageIndex)) {
screenStack.add(_pageIndex);
}
},
);
},
title: const Text("Education"),
),
ListTile(
onTap: () {
Navigator.of(context).pop();
setState(
() {
_drawerIndex = 4;
},
);
},
title: const Text("Others"),
)
],
),
),
),
bottomNavigationBar: BottomNavigationBar(
type: BottomNavigationBarType.fixed,
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(Icons.business),
label: 'Business',
),
BottomNavigationBarItem(
icon: Icon(Icons.computer),
label: 'Technology',
),
BottomNavigationBarItem(
icon: Icon(Icons.book),
label: 'Education',
),
],
currentIndex: _pageIndex,
onTap: (int index) {
setState(
() {
_pageIndex = index;
_drawerIndex = _pageIndex;
if (_pageIndex == 0) {
screenStack = [0];
} else if (!screenStack.contains(_pageIndex)) {
screenStack.add(_pageIndex);
}
},
);
},
),
);
}
}
// ignore: must_be_immutable
class DetailRoute extends StatelessWidget {
late TextEditingController? textEditingController;
int? index;
DetailRoute({Key? key, this.textEditingController, this.index})
: super(key: key);
@override
Widget build(BuildContext context) {
return Container();
}
}
CodePudding user response:
Try this approach-
class BottomNavBar extends StatefulWidget {
const BottomNavBar({Key? key}) : super(key: key);
@override
_BottomNavBarState createState() => _BottomNavBarState();
}
class _BottomNavBarState extends State<BottomNavBar> {
int pageIndex = 0;
List<Widget> pageList = <Widget>[Home(), Profile(), Setting()];
@override
Widget build(BuildContext context) {
return Scaffold(
body: pageList[pageIndex],
bottomNavigationBar: BottomNavigationBar(
fixedColor: Colors.redAccent[400],
currentIndex: pageIndex,
onTap: (value) {
setState(() {
pageIndex = value;
});
},
// type: BottomNavigationBarType.fixed,
items: [
BottomNavigationBarItem(
activeIcon: Icon(
Icons.home,
color: AppColors.black,
),
icon: Icon(
Icons.home,
color: AppColors.grey,
),
label: ""),
BottomNavigationBarItem(
activeIcon: Icon(
Icons.person,
color: AppColors.black,
),
icon: Icon(
Icons.person,
color: AppColors.grey,
),
label: ""),
BottomNavigationBarItem(
activeIcon: Icon(
Icons.settings,
color: AppColors.black,
),
icon: Icon(
Icons.settings,
color: AppColors.grey,
),
label: ""),
]));
}
}