Reputation: 23
I'm trying to implement both a Drawer and the Bottom Navigation Bar. The below class NavigationHomeScreen is my home screen and when the user clicks a menu item in the Drawer the Changeindex function updates the screenView
I would like to know how I can similarly update the screenView
but from the BottomNavigationBarApp
using the onTabTapped
method.
class NavigationHomeScreen extends StatefulWidget {
@override
_NavigationHomeScreenState createState() => _NavigationHomeScreenState();
}
class _NavigationHomeScreenState extends State<NavigationHomeScreen> {
Widget screenView;
DrawerIndex drawerIndex;
@override
void initState() {
drawerIndex = DrawerIndex.HOME;
screenView = const MyHomePage();
super.initState();
}
@override
Widget build(BuildContext context) {
return Container(
color: AppTheme.nearlyWhite,
child: SafeArea(
top: false,
bottom: false,
child: Scaffold(
appBar: emptyAppbar(),
backgroundColor: AppTheme.nearlyWhite,
body: DrawerUserController(
screenIndex: drawerIndex,
drawerWidth: MediaQuery.of(context).size.width * 0.75,
onDrawerCall: (DrawerIndex drawerIndexdata) {
changeIndex(drawerIndexdata);
//callback from drawer for replace screen as user need with passing DrawerIndex(Enum index)
},
screenView: screenView,
//we replace screen view as we need on navigate starting screens like MyHomePage, HelpScreen, FeedbackScreen, etc...
),
bottomNavigationBar:BottomNavigationBarApp(context, 1),
),
),
);
}
void changeIndex(DrawerIndex drawerIndexdata) {
if (drawerIndex != drawerIndexdata) {
drawerIndex = drawerIndexdata;
if (drawerIndex == DrawerIndex.HOME) {
setState(() {
screenView = const MyHomePage();
});
} else if (drawerIndex == DrawerIndex.Help) {
setState(() {
screenView = HelpScreen();
});
} else if (drawerIndex == DrawerIndex.FeedBack) {
setState(() {
screenView = FeedbackScreen();
});
} else if (drawerIndex == DrawerIndex.Invite) {
setState(() {
screenView = InviteFriend();
});
} else {
//do in your way......
}
}
}
}
class BottomNavigationBarApp extends StatelessWidget {
final int bottomNavigationBarIndex;
final BuildContext context;
const BottomNavigationBarApp(this. context, this.bottomNavigationBarIndex);
void onTabTapped(int index) {
}
@override
Widget build(BuildContext context) {
return BottomNavigationBar(
currentIndex: bottomNavigationBarIndex,
type: BottomNavigationBarType.fixed,
selectedFontSize: 10,
selectedLabelStyle: TextStyle(color: CustomColors.BlueDark),
selectedItemColor: CustomColors.BlueDark,
unselectedFontSize: 10,
items: [
BottomNavigationBarItem(
icon: Container(
margin: EdgeInsets.only(bottom: 5),
child: Image.asset(
'assets/images/home.png',
color: (bottomNavigationBarIndex == 1)
? CustomColors.BlueDark
: CustomColors.TextGrey,
),
),
title: Text('Home'),
),
BottomNavigationBarItem(
icon: Container(
margin: EdgeInsets.only(bottom: 5),
child: Image.asset(
'assets/images/task.png',
color: (bottomNavigationBarIndex == 0)
? CustomColors.BlueDark
: CustomColors.TextGrey,
),
),
title: Text('Appointments'),
),
],
onTap: onTabTapped,
);
}
}
Upvotes: 1
Views: 2150
Reputation: 2303
The best way to do it and also recommended by the Flutter development team is to use the provider package
from flutter to manage the state between those widgets.
The top answer does solves your issue if its small app, but as your application grows, you most likely want to change things far up a widget tree which makes functions impractical.
Upvotes: 0
Reputation: 1939
You can pass a reference to a function down to a widget. Something like this:
In your HomeScreen:
void updateScreenView() {
//Do changes you want here. Dont forget to setState!
}
In your BottomNavigationBarApp (edit: Function
must start with a capital F):
final int bottomNavigationBarIndex;
final BuildContext context;
final Function tapHandler;
const BottomNavigationBarApp(this. context, this.bottomNavigationBarIndex, this.tapHandler);
and then just pass the reference on:
bottomNavigationBar:BottomNavigationBarApp(context, 1, updateScreenView),
And assign the function to your handler.
onTap: () => tapHandler(),
Upvotes: 1