Reputation: 1315
I'm still a beginner at flutter and I want to create a flutter mobile app with a side drawer and a bottom navigation tab bar. I have created my app with a side drawer and a bottom navigation, but my problem is I want to open the Home page from both drawer and bottom navigation tab.
Now the drawer is opening the home page but it's not showing the bottom navigator.
here's my code
main.dart
import 'package:discover_me/screens/home.dart';
import 'package:discover_me/screens/search.dart';
import 'package:discover_me/tabs/tabspage.dart';
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
scaffoldBackgroundColor: Colors.white,
primaryColor: Colors.white
),
home: TabsPage(),
debugShowCheckedModeBanner: false,
routes: {
// '/': (context) => Home(),
'/home': (context) => Home(),
'/search': (context) => SearchPage(),
},
);
}
}
tabspage.dart
import 'package:discover_me/shared/bottom_tabs.dart';
import 'package:flutter/material.dart';
class TabsPage extends StatefulWidget {
@override
_TabsPageState createState() => _TabsPageState();
}
class _TabsPageState extends State<TabsPage> {
int _selectedIndex = 0;
static const TextStyle optionStyle =
TextStyle(fontSize: 30, fontWeight: FontWeight.bold);
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Scaffold(
body: IndexedStack(
index: _selectedIndex,
children: [
for (final tabItem in TabNavigationItem.items) tabItem.page,
],
),
// drawer: SideMenu(),
),
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,
),
);
}
}
bottom_tabs.dart
import 'package:discover_me/screens/home.dart';
import 'package:discover_me/screens/search.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
class TabNavigationItem {
final Widget page;
final Widget title;
final Icon icon;
TabNavigationItem({this.page, this.title, this.icon});
static List<TabNavigationItem> get items => [
TabNavigationItem(
page: Home(),
icon: Icon(Icons.home),
title: Text("Home"),
),
TabNavigationItem(
page: SearchPage(),
icon: Icon(Icons.home),
title: Text("Home"),
),
TabNavigationItem(
page: Home(),
icon: Icon(Icons.home),
title: Text("Home"),
),
];
}
home.dart
import 'package:discover_me/jsn_objects/visit_places.dart';
import 'package:discover_me/tabs/tabspage.dart';
import 'package:discover_me/widgets/side_menu.dart';
import 'package:flutter/material.dart';
import 'dart:convert';
class Home extends StatefulWidget {
@override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
bool expanded = false;
@override
Widget build(BuildContext context) {
return Scaffold(
drawer: SideMenu(),
appBar: AppBar(
leading: Builder(
builder: (BuildContext context) {
return RotatedBox(
quarterTurns: 1,
child: IconButton(
icon: Icon(
Icons.bar_chart_rounded,
color: Colors.black,
),
onPressed: () => Scaffold.of(context).openDrawer(),
),
);
},
),
backgroundColor: Colors.white,
elevation: 0.0,
actions: [
IconButton(
color: Colors.black,
icon: Icon(Icons.search),
onPressed: () {
Navigator.pushNamed(
context, '/search'
);
}),
],
),
body: Column(
children: [
Container(color: Colors.green, height: 100),
AnimatedContainer(
duration: const Duration(milliseconds: 200),
height: expanded ? 120 : 0,
child: Container(height: 120, color: Colors.red),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
FloatingActionButton(
heroTag: null,
child:
Icon(expanded ? Icons.arrow_upward : Icons.arrow_downward),
onPressed: () => setState(() {
expanded = !expanded;
}),
),
],
),
],
),
);
}
}
I want to call Home Page with the bottom navigation from the drawer. Could you please help me with this?
Upvotes: 3
Views: 4645
Reputation: 1315
Finally, I have managed to solve my issue.
I have add a constructor parameter to TabsPage and pass the value when the page called from the side drawer.
here's the solution
main.dart
import 'package:flutter/material.dart';
import 'package:tabsdrawer/tabs/tabspage.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
scaffoldBackgroundColor: Colors.white, primaryColor: Colors.white),
home: TabsPage(selectedIndex: 0),
debugShowCheckedModeBanner: false,
);
}
}
sidemenu.dart file
import 'package:flutter/material.dart';
import 'package:tabsdrawer/tabs/tabspage.dart';
class SideMenu extends StatefulWidget {
@override
_SideMenuState createState() => _SideMenuState();
}
class _SideMenuState extends State<SideMenu> {
@override
Widget build(BuildContext context) {
return Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: [
DrawerHeader(
child: Text(
'Discover Sri Lanka',
style: TextStyle(color: Colors.white, fontSize: 25),
),
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(10.0),
bottomRight: Radius.circular(10.0)),
color: Colors.white,
image: DecorationImage(
fit: BoxFit.fill, image: AssetImage('assets/sideimg.jpg'))),
),
ListTile(
leading: Icon(Icons.home),
title: Text('Home'),
onTap: () => {
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => TabsPage(selectedIndex: 0)),
)
},
),
ListTile(
leading: Icon(Icons.search),
title: Text('Search'),
onTap: () => {
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => TabsPage(selectedIndex: 1)),
),
},
),
ListTile(
leading: Icon(Icons.settings),
title: Text('Profile'),
onTap: () => {
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => TabsPage(selectedIndex: 2)),
),
},
),
],
),
);
}
}
tabspage.dart
import 'package:flutter/material.dart';
import 'package:tabsdrawer/tabs/bottom_tabs.dart';
class TabsPage extends StatefulWidget {
int selectedIndex = 0;
TabsPage({this.selectedIndex});
@override
_TabsPageState createState() => _TabsPageState();
}
class _TabsPageState extends State<TabsPage> {
int _selectedIndex = 0;
void _onItemTapped(int index) {
setState(() {
widget.selectedIndex = index;
_selectedIndex = widget.selectedIndex;
print(_selectedIndex);
});
}
@override
void initState() {
_onItemTapped(widget.selectedIndex);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Scaffold(
body: IndexedStack(
index: widget.selectedIndex,
children: [
for (final tabItem in TabNavigationItem.items) tabItem.page,
],
),
),
bottomNavigationBar: BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
title: Text('Home'),
),
BottomNavigationBarItem(
icon: Icon(Icons.search),
title: Text('Search'),
),
BottomNavigationBarItem(
icon: Icon(Icons.verified_user),
title: Text('Profile'),
),
],
currentIndex: _selectedIndex,
selectedItemColor: Colors.amber[800],
onTap: _onItemTapped,
),
);
}
}
bottom_tabs.dart
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:tabsdrawer/screens/home.dart';
import 'package:tabsdrawer/screens/profile.dart';
import 'package:tabsdrawer/screens/search.dart';
class TabNavigationItem {
final Widget page;
final Widget title;
final Icon icon;
TabNavigationItem({this.page, this.title, this.icon});
static List<TabNavigationItem> get items => [
TabNavigationItem(
page: Home(),
icon: Icon(Icons.home),
title: Text("Home"),
),
TabNavigationItem(
page: Search(),
icon: Icon(Icons.search),
title: Text("Search"),
),
TabNavigationItem(
page: Profile(),
icon: Icon(Icons.home),
title: Text("Home"),
),
];
}
home.dart
import 'package:flutter/material.dart';
import 'package:tabsdrawer/sidemenu/side_menu.dart';
class Home extends StatefulWidget {
@override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
@override
Widget build(BuildContext context) {
return Scaffold(
drawer: SideMenu(),
appBar: AppBar(
leading: Builder(
builder: (BuildContext context) {
return RotatedBox(
quarterTurns: 1,
child: IconButton(
icon: Icon(
Icons.bar_chart_rounded,
color: Colors.black,
),
onPressed: () => Scaffold.of(context).openDrawer(),
),
);
},
),
backgroundColor: Colors.white,
elevation: 0.0,
actions: [
IconButton(
color: Colors.black,
icon: Icon(Icons.search),
onPressed: () {
Navigator.pushNamed(context, '/search');
}),
],
),
body: Center(
child: Text('Home Page'),
),
);
}
}
I have wrote an article mentioning the whole solution in here, https://medium.com/@prabhashibuddhima/flutter-how-to-make-flutter-side-drawer-side-menu-work-with-bottom-navigation-bar-bottom-tab-ce66a95e25fe
Upvotes: 3
Reputation: 71
It's not showing BottomNavigationBar because you didn't call it in your HomePage. You can create a generic BottomNavigationBar and call it wherever you want to see it and you can control the selected tab with setting it to provider if you want.
So basically your Home page should be like this :
import 'package:discover_me/jsn_objects/visit_places.dart';
import 'package:discover_me/tabs/tabspage.dart';
import 'package:discover_me/widgets/side_menu.dart';
import 'package:flutter/material.dart';
import 'dart:convert';
class Home extends StatefulWidget {
@override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
bool expanded = false;
@override
Widget build(BuildContext context) {
return Scaffold(
drawer: SideMenu(),
appBar: AppBar(
leading: Builder(
builder: (BuildContext context) {
return RotatedBox(
quarterTurns: 1,
child: IconButton(
icon: Icon(
Icons.bar_chart_rounded,
color: Colors.black,
),
onPressed: () => Scaffold.of(context).openDrawer(),
),
);
},
),
backgroundColor: Colors.white,
elevation: 0.0,
actions: [
IconButton(
color: Colors.black,
icon: Icon(Icons.search),
onPressed: () {
Navigator.pushNamed(context, '/search');
}),
],
),
body: Column(
children: [
Container(color: Colors.green, height: 100),
AnimatedContainer(
duration: const Duration(milliseconds: 200),
height: expanded ? 120 : 0,
child: Container(height: 120, color: Colors.red),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
FloatingActionButton(
heroTag: null,
child:
Icon(expanded ? Icons.arrow_upward : Icons.arrow_downward),
onPressed: () => setState(() {
expanded = !expanded;
}),
),
],
),
],
),
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,
),
);
}
}
But it's not good to create new BottomNavigationBar for your every page. I suggest you to create a generic one
Upvotes: 4