i have a bottomnavigation bar in flutter ,what i want is on click of the individual widgets of the bottombar it should navigate me to the next page
Widget _bottemTab() {
return new BottomNavigationBar(
currentIndex: _currentIndex,
onTap:(newIndex) => setState((){_currentIndex = newIndex;}),
type: BottomNavigationBarType.fixed,
items: [
new BottomNavigationBarItem(
icon: Image.asset(
"assets/home.png",
width: 24.0,
height: 24.0,
),
title: Text(
'Home',
),
),
new BottomNavigationBarItem(
icon: Image.asset(
"assets/shopping-bagg.png",
width: 24.0,
height: 24.0,
),
title: Text(
'Mall',
)),
new BottomNavigationBarItem(
icon: Image.asset(
"assets/qr-code.png",
width: 24.0,
height: 24.0,
),
title: Text(
'Scan',
)),
new BottomNavigationBarItem(
icon: Image.asset(
"assets/bank.png",
width: 24.0,
height: 24.0,
),
title: Text(
'Bank',
)),
new BottomNavigationBarItem(
icon: Image.asset(
"assets/delivery.png",
width: 24.0,
height: 24.0,
),
title: Text(
'Inbox',
)),
]);
}
i want is on click of the individual widgets of the bottombar it should navigate me to the next page which i have created separately for each menu items of bottom navigation view..any help is appreciated
In your build() method, you can add this logic.
#override
Widget build(BuildContext context) {
Widget widget = Container(); // default
switch (_currentIndex) {
case 0:
widget = FirstPage();
break;
case 1:
widget = SecondPage();
break;
case 2:
widget = ThirdPage();
break;
}
return Scaffold(
body: widget,
// ...
);
}
Update:
I'm not sure how you did that, here you can see a small example of doing it right way.
int _index = 0;
#override
Widget build(BuildContext context) {
Widget child = Container();
switch(_index) {
case 0:
child = FlutterLogo(colors: Colors.orange);
break;
case 1:
child = FlutterLogo();
break;
}
return Scaffold(
appBar: AppBar(),
bottomNavigationBar: _bottomTab(),
body: SizedBox.expand(child: child),
);
}
Widget _bottomTab() {
return BottomNavigationBar(
currentIndex: _index,
onTap: (int index) => setState(() => _index = index),
backgroundColor: Colors.deepPurple,
items: [
BottomNavigationBarItem(icon: Icon(Icons.looks_one), title: Text("1")),
BottomNavigationBarItem(icon: Icon(Icons.looks_two), title: Text("2")),
],
);
}
Hope this helps.
int _selectedIndex = 0;
static const TextStyle optionStyle = TextStyle(fontSize: 30, fontWeight: FontWeight.bold);
static const _pages = <Widget>[
Home(),//this is a stateful widget on a separate file
Business(),//this is a stateful widget on a separate file
School(),//this is a stateful widget on a separate file
];
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('BottomNavigationBar Sample'),
),
body: Center(
child: _pages.elementAt(_selectedIndex),
),
bottomNavigationBar: BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
title: Text('Home'),
),
BottomNavigationBarItem(
icon: Icon(Icons.business),
title: Text('Business'),
),
BottomNavigationBarItem(
icon: Icon(Icons.school),
title: Text('School'),
),
],
currentIndex: _selectedIndex,
selectedItemColor: Colors.amber[800],
onTap: _onItemTapped,
),
);
}
Related
So I'm working on project with flutter. First I want to know if using a bottom Navigation Bar is better than creating a container for it. Now my question, how do I navigate to a page by using this bottom Navigation bar? Like should I build an entire page and bottom navigation bar for each one? OR Can I build everything in one place ?
This a part of it
void main() => runApp(MyApp());
class ProfilePage extends StatefulWidget {
#override
State<ProfilePage> createState() => _ProfilePageState();
}
class _ProfilePageState extends State<ProfilePage> {
int _selectedIndex = 0;
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
});
}
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
appBar: AppBar(
title: Text('HOME'),
centerTitle: true,
backgroundColor: Colors.green[900],
leading: IconButton(
icon: Icon(Icons.arrow_back),
onPressed: () {
Navigator.pop(context);
},
),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [],
),
bottomNavigationBar: BottomNavigationBar(
backgroundColor: Colors.green[900],
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(
Icons.home,
),
label: 'Home',
backgroundColor: Colors.green[900],
),
BottomNavigationBarItem(
icon: Icon(
Icons.calendar_today,
),
label: 'Days',
backgroundColor: Colors.green[900],
),
BottomNavigationBarItem(
icon: Icon(
Icons.local_activity,
),
label: 'Activity',
backgroundColor: Colors.green[900],
),
BottomNavigationBarItem(
icon: Icon(
Icons.settings,
),
label: 'Settings',
backgroundColor: Colors.green[900],
),
],
currentIndex: _selectedIndex,
selectedItemColor: Colors.white,
onTap: _onItemTapped,
),
),
);
}
}
This is how it looks but don't know how to navigate between screens.
you PageView class for change pages
Change Column to Pageview
final PageController controller = PageController();
return PageView(
/// [PageView.scrollDirection] defaults to [Axis.horizontal].
/// Use [Axis.vertical] to scroll vertically.`enter code here`
controller: controller,
children: const <Widget>[
Center(
child: Text('First Page'),
),
Center(
child: Text('Second Page'),
),
Center(
child: Text('Third Page'),
)
],
);
}
change in your method
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
controller.jumpToPage(index);
});
}
You don't need to create a BnB for each screen, you can create a navbar on the main screen
and in the build method return the corresponding page, based on the selected index.
I have a bottom bar that is supposed to switch between screens when selected but I do not know how to make that work. I know is all contained in the buildpages() widget. Can you guide me through?
Widget buildBottomBar() {
final style = TextStyle(color: Colors.white);
return BottomNavigationBar(
backgroundColor: Colors.deepOrange,
selectedItemColor: Colors.white,
unselectedItemColor: Colors.black,
showSelectedLabels: true,
showUnselectedLabels: false,
selectedLabelStyle: TextStyle(color: Colors.black54),
currentIndex: index,
items: [
BottomNavigationBarItem(
icon: Text('App', style: style),
label: 'Idioms List',
activeIcon: Icon(Icons.list)
),
BottomNavigationBarItem(
icon: Text('FAVORITES', style: style),
label: 'Favorited',
activeIcon: Icon(Icons.favorite_border_rounded)
),
],
onTap: (int index) => setState(() => this.index = index),
);
}
Widget buildPages() {
switch (index) {
case 0:
return FavoriteScreen();
case 1:
return MainPage();
default:
return Container();
}
}
}
you need to create a page for bottom nav bar and
give stful widget then create a list of page like this
static const List<Widget> _widgetOptions = <Widget>[
YorPageclass1(),
YourPageclass2(), etc...];
and create a function for Ontap like
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
});}
and create a scaffold widget for pages
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('BottomNavigationBar Sample'),
),
body: Center(
child: _widgetOptions.elementAt(_selectedIndex),
),
bottomNavigationBar: BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(Icons.business),
label: 'Business',
),
BottomNavigationBarItem(
icon: Icon(Icons.school),
label: 'School',
),
],
currentIndex: _selectedIndex,
selectedItemColor: Colors.amber[800],
onTap: _onItemTapped,
),
);
}
I hope the my title is enough to understand my problem, How to put a list item in bottomnavigation using flutter? if not please refer in the picture below and code i provided.
return Scaffold(
bottomNavigationBar: BottomNavigationBar(
type: BottomNavigationBarType.fixed,
currentIndex: _currentIndex,
backgroundColor: Colors.orangeAccent,
selectedItemColor: Colors.white,
unselectedItemColor: colorScheme.onSurface.withOpacity(.40),
selectedLabelStyle: textTheme.caption,
unselectedLabelStyle: textTheme.caption,
onTap: (value) {
// Respond to item press.
setState(() => _currentIndex = value);
},
items: [
BottomNavigationBarItem(
title: Text('Clothes'),
icon: Icon(Icons.design_services_rounded),
),
BottomNavigationBarItem(
title: Text('Colors'),
icon: Icon(Icons.colorize_rounded),
),
BottomNavigationBarItem(
title: Text('Ideas'),
icon: Icon(Icons.lightbulb_outline_rounded),
),
BottomNavigationBarItem(
title: Text('Profile'),
icon: Icon(Icons.face_rounded),
),
],
),
);
}
}
if i clicked the Clothes , this will happen.
Edit 1:
How this is done is as follows:
// Keep this outside your Widget as it is a constant.
final List<Widget> _widgets = <Widget>[
ClothesPage(),
ColorsPage(),
IdeasPage(),
ProfilePage(),
];
return Scaffold(
// This body is new.
body: _widgets[_currentIndex],
bottomNavigationBar: BottomNavigationBar(
type: BottomNavigationBarType.fixed,
currentIndex: _currentIndex,
backgroundColor: Colors.orangeAccent,
selectedItemColor: Colors.white,
unselectedItemColor: colorScheme.onSurface.withOpacity(.40),
selectedLabelStyle: textTheme.caption,
unselectedLabelStyle: textTheme.caption,
onTap: (value) {
_currentIndex = value;
showDialog(
context: context,
barrierDismissible: true,
builder: (BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
_widgets[_currentIndex],
SizedBox(
// Use whatever height you desire.
height: 90,
),
],
);
},
);
},
items: [
BottomNavigationBarItem(
title: Text('Clothes'),
icon: Icon(Icons.design_services_rounded),
),
BottomNavigationBarItem(
title: Text('Colors'),
icon: Icon(Icons.colorize_rounded),
),
BottomNavigationBarItem(
title: Text('Ideas'),
icon: Icon(Icons.lightbulb_outline_rounded),
),
BottomNavigationBarItem(
title: Text('Profile'),
icon: Icon(Icons.face_rounded),
),
],
),
);
// I have put a card here, you can put any other Widget for the same.
// Do the same for others.
class ProfilePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Card(
color: Colors.white,
child: Padding(
padding: EdgeInsets.all(10),
child: Text(
"Profile",
),
),
);
}
}
Now, I hope this is what you expect to do via the Bottom Navigation Bar.
I'm trying to navigate to different pages within my app using the icons in my bottom navigation bar. I have tried many tutorials and can't seem to work out the best way to achieve this. I have created my Homepage (code below) and 2 additional pages, Inbox and Signin, both return simple scaffolds.
Firstly i'm interested to know if this is the best way to do what i'm trying to achieve and second, how can my code be altered to allow me to navigate to different pages depending on which icon is tapped. I'm aware that the code below doesn't execute, i'm just trying to show what i've tried.
My code:
class HomePage extends StatefulWidget {
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
_onTap(int index) {
Navigator.of(context)
.push(MaterialPageRoute<Null>(builder: (BuildContext context) {
return _children[_currentIndex];
}));}
final List<Widget> _children = [
HomePage(),
InboxPage(),
SignInPage()
];
int _currentIndex = 0;
#override
Widget build(BuildContext context) {
SizeConfig().init(context);
return Scaffold(
appBar: PreferredSize(preferredSize: Size(double.infinity, 75),
child: AppBar(
elevation: 0.0,
centerTitle: false,
title: Column(
children: <Widget>[
Align(
alignment: Alignment.centerLeft,
child: Text(
currentDate,
textAlign: TextAlign.left,
style: TextStyle(
color: titleTextColor,
fontWeight: subTitleFontWeight,
fontFamily: titleFontFamily,
fontSize: subTitleFontSize),
),
),
SizedBox(
height: 15,
),
Align(
alignment: Alignment.centerLeft,
child: Text(
'Some text here',
style: TextStyle(
color: titleTextColor,
fontWeight: titleTextFontWeight,
fontFamily: titleFontFamily,
fontSize: titleFontSize),
),
),
],
),
backgroundColor: kPrimaryColor,
shape: titleBarRounding
),
),
body: BodyOne(),
bottomNavigationBar: BottomNavigationBar(
currentIndex: _currentIndex,
type: BottomNavigationBarType.fixed,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.home),
title: Text('Home'),
),
BottomNavigationBarItem(
icon: Icon(Icons.mail),
title: Text('Inbox'),
),
BottomNavigationBarItem(
icon: Icon(Icons.account_circle),
title: Text('Account'),
)
],
onTap: () => _onTap(_currentIndex),
),);
}
}
Thanks in advance.
The screen you are in can't be part of the Screens you're navigating to and you don't need to push a new screen each time you just have to change selectedPage, this is an example of how it should look:
import 'package:flutter/material.dart';
class HomePage extends StatefulWidget {
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
int selectedPage = 0;
final _pageOptions = [
HomeScreen(),
InboxScreen(),
SignInScreen()
];
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: _pageOptions[selectedPage],
bottomNavigationBar: BottomNavigationBar(
items: [
BottomNavigationBarItem(icon: Icon(Icons.home, size: 30), title: Text('Home')),
BottomNavigationBarItem(icon: Icon(Icons.mail, size: 30), title: Text('Inbox')),
BottomNavigationBarItem(icon: Icon(Icons.account_circle, size: 30), title: Text('Account')),
],
selectedItemColor: Colors.green,
elevation: 5.0,
unselectedItemColor: Colors.green[900],
currentIndex: selectedPage,
backgroundColor: Colors.white,
onTap: (index){
setState(() {
selectedPage = index;
});
},
)
);
}
}
Let me know if you need more explanation.
The input parameter of the _onTap function is unused and needs to be deleted.
_onTap() {
Navigator.of(context)
.push(MaterialPageRoute(builder: (BuildContext context) => _children[_currentIndex])); // this has changed
}
In the onTap of the BottomNavigationBar you need to change the _currentIndex and then call the _onTap function which navigates to the selected screen.
onTap: (index) {
setState(() {
_currentIndex = index;
});
_onTap();
},
You can add this BottomNavigationBar to all of the screens, but pay attention to the initial value of the _currentIndex that changes according to the screen you're putting the BottomNavigationBar in.
Full code:
_onTap() { // this has changed
Navigator.of(context)
.push(MaterialPageRoute(builder: (BuildContext context) => _children[_currentIndex])); // this has changed
}
final List<Widget> _children = [
HomePage(),
InboxPage(),
SignInPage()
];
#override
Widget build(BuildContext context) {
SizeConfig().init(context);
return Scaffold(
appBar: PreferredSize(
preferredSize: Size(double.infinity, 75),
child: AppBar(
elevation: 0.0,
centerTitle: false,
title: Column(
children: <Widget>[
Align(
alignment: Alignment.centerLeft,
child: Text(
currentDate,
textAlign: TextAlign.left,
style: TextStyle(
color: titleTextColor,
fontWeight: subTitleFontWeight,
fontFamily: titleFontFamily,
fontSize: subTitleFontSize),
),
),
SizedBox(
height: 15,
),
Align(
alignment: Alignment.centerLeft,
child: Text(
'Some text here',
style: TextStyle(
color: titleTextColor,
fontWeight: titleTextFontWeight,
fontFamily: titleFontFamily,
fontSize: titleFontSize),
),
),
],
),
backgroundColor: kPrimaryColor,
shape: titleBarRounding
),
),
body: BodyOne(),
body: Container(),
bottomNavigationBar: BottomNavigationBar(
currentIndex: _currentIndex,
type: BottomNavigationBarType.fixed,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.home),
title: Text('Home'),
),
BottomNavigationBarItem(
icon: Icon(Icons.mail),
title: Text('Inbox'),
),
BottomNavigationBarItem(
icon: Icon(Icons.account_circle),
title: Text('Account'),
)
],
onTap: (index) { // this has changed
setState(() {
_currentIndex = index;
});
_onTap();
},
),
);
}
The best way to do it is creating a wrapper to your screens. Like this:
class Wrapper extends StatefulWidget {
Wrapper();
_WrapperState createState() => _WrapperState();
}
class _WrapperState extends State<Wrapper> {
int _currentIndex = 0;
final List<Widget> _children = [
HomePage(),
InboxPage(),
SignInPage()
];
void onTabTapped(int index) {
setState(() {
_currentIndex = index;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: _children[_currentIndex],
bottomNavigationBar: BottomNavigationBar(
onTap: onTabTapped,
currentIndex: _currentIndex,
items:[
BottomNavigationBarItem(
icon: Icon(Icons.home),
title: Text('Home'),
),
BottomNavigationBarItem(
icon: Icon(Icons.mail),
title: Text('Inbox'),
),
BottomNavigationBarItem(
icon: Icon(Icons.account_circle),
title: Text('Account'),
)
],
),
);
}
}
Firstly I used AppBar to change pages, but I noticed BottomNavBar has better properties to do that. But it would be great if someone gave me a clue to create navigation at the top of the screen.
This BottomNavBar doesn't work, gives error 'each child must be laid once':
Widget build(BuildContext context) {
return new Scaffold(
//appBar: bar(context),
body: new Container(
key: _formKey,
padding: const EdgeInsets.all(30),
child: new Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Positioned(
bottom: 0.0,
left: 0.0,
right: 0.0,
child: BottomNavigationBar(
items: <BottomNavigationBarItem>[
new BottomNavigationBarItem(
icon: const Icon(Icons.home), title: new Text("Home")),
new BottomNavigationBarItem(
icon: const Icon(Icons.work),
title: new Text("Self Help")),
new BottomNavigationBarItem(
icon: const Icon(Icons.face),
title: new Text("Profile"))
],
selectedItemColor: colorGold,
)),
],
),
),
);
}
}
And this is my AppBar where I tried to change color of the active icon:
AppBar(
automaticallyImplyLeading: false,
title: Center(
child: Row(mainAxisAlignment: MainAxisAlignment.center, children: <
Widget>[
iconButton(
Icons.home,
),
iconButton(
Icons.work,
),
iconButton(
Icons.face,
)),]))```
If I'm not wrong , you are supposing to this:
Use PreferredSize widget in your app bar
Full code:
class TabBarHomeScreen extends StatefulWidget {
#override
_TabBarHomeScreenState createState() => _TabBarHomeScreenState();
}
class _TabBarHomeScreenState extends State<TabBarHomeScreen> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Top Navigation tab bar demo"),
),
body: TopNavigationBar(),
);
}
}
class TopNavigationBar extends StatefulWidget {
#override
_TopNavigationBarState createState() => _TopNavigationBarState();
}
class _TopNavigationBarState extends State<TopNavigationBar> with SingleTickerProviderStateMixin {
int tabIndex = 0;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar:PreferredSize(
preferredSize: Size.fromHeight(kToolbarHeight),
child: BottomNavigationBar(
//elevation: 0.0,
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home, color: Colors.grey,),
activeIcon: Icon(Icons.home, color: Colors.blue,),
title: Text('')
),
BottomNavigationBarItem(
icon: Icon(Icons.mail, color: Colors.grey,),
activeIcon: Icon(Icons.mail, color: Colors.blue,),
title: Text('')
),
BottomNavigationBarItem(
icon: Icon(Icons.account_circle, color: Colors.grey,),
activeIcon: Icon(Icons.account_circle, color: Colors.blue,),
title: Text('')
)
],
currentIndex: tabIndex,
selectedItemColor: Colors.blueAccent,
onTap: (int index){
setState(() {
tabIndex = index;
});
},
),
),
body: Container(
color: Colors.white,
child: tabIndex ==0 ?MyHomeScreen()
:tabIndex == 1? MyMailScreen(): MyProfileScreen()
),
);
}
}
class MyHomeScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child:Text("My Home Screen")
),
);
}
}
class MyMailScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child:Text("My Mail Screen")
),
);
}
}
class MyProfileScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child:Text("My Profile Screen")
),
);
}
}