This is the code without error messages:
import 'dart:ui';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
class MyStatefulWidget extends StatefulWidget {
const MyStatefulWidget({Key? key}) : super(key: key);
#override
State<MyStatefulWidget> createState() => BottomNavigation();
}
/// This is the private State class that goes with MyStatefulWidget.
class BottomNavigation extends State<MyStatefulWidget> {
int _selectedIndex = 0;
List<Widget> _widgetOptions= <Widget>[
Text('Home'),
Text('Message')
];
static const TextStyle optionStyle =
TextStyle(fontSize: 30, fontWeight: FontWeight.bold);
void _onItemTapped(int index) {
setState(() {
_selectedIndex=index;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
actions: <Widget>[
IconButton(icon: Icon(Icons.search), onPressed: () {}),
],
),
body: Container(
decoration: BoxDecoration(
image: DecorationImage(
image:
AssetImage("assets/OptimizeYourFood/OptimizeYourFood2.png"),
fit: BoxFit.cover,
),
color: Colors.transparent)
),
bottomNavigationBar: BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.local_dining),
label: 'Reduce',
),
BottomNavigationBarItem(
icon: Icon(FontAwesomeIcons.recycle),
label: 'Reuse and recycle',
),
],
currentIndex: _selectedIndex,
selectedItemColor: Colors.amber[800],
onTap: _onItemTapped,
),
);
}
}
[Nothing comes out of bottom navigation bar items][1]
..................................................................................................................................................................................................This is the end. This is the end. This is the end. This is the end. This is the end.
New Code
New Picture
You are changing the index but not the UI. use _widgetOptions on body. You can directly use body:_widgetOptions[_selectedIndex ] .
class MyStatefulWidget extends StatefulWidget {
const MyStatefulWidget({Key? key}) : super(key: key);
#override
State<MyStatefulWidget> createState() => BottomNavigation();
}
/// This is the private State class that goes with MyStatefulWidget.
class BottomNavigation extends State<MyStatefulWidget> {
int _selectedIndex = 0;
List<Widget> _widgetOptions = <Widget>[Text('Home'), Text('Message')];
static const TextStyle optionStyle =
TextStyle(fontSize: 30, fontWeight: FontWeight.bold);
void _onItemTapped(int index) {
print("tapped $index");
setState(() {
_selectedIndex = index;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
actions: <Widget>[
IconButton(icon: Icon(Icons.search), onPressed: () {}),
],
),
body: Column(
children: [
_widgetOptions[_selectedIndex]
// Container(
// decoration: BoxDecoration(
// image: DecorationImage(
// image:
// AssetImage("assets/OptimizeYourFood/OptimizeYourFood2.png"),
// fit: BoxFit.cover,
// ),
// color: Colors.transparent)),
],
),
bottomNavigationBar: BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.local_dining),
label: 'Reduce',
),
BottomNavigationBarItem(
icon: Icon(Icons.ac_unit),
// Icon(FontAwesomeIcons.recycle),
label: 'Reuse and recycle',
),
],
currentIndex: _selectedIndex,
selectedItemColor: Colors.amber[800],
onTap: _onItemTapped,
),
);
}
}
It will use the items array index.
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem( // <- index 0
icon: Icon(Icons.local_dining),
label: 'Reduce',
),
BottomNavigationBarItem( // <- index 1
icon: Icon(FontAwesomeIcons.recycle),
label: 'Reuse and recycle',
),
...
],
Related
I am trying to apply persistent_bottom_nav_bar but I keep getting error. I got similar answers and tried to follow https://pub.dev/packages/persistent_bottom_nav_bar
These are the errors that I keep getting.
The method '_BottomBarState' isn't defined for the type 'BottomBar'. & 1 positional argument(s) expected, but 0 found.
class BottomBar extends StatefulWidget {
const BottomBar({Key? key}) : super(key: key);
#override
State<BottomBar> createState() => _BottomBarState();
}
PersistentTabController _controller = PersistentTabController(initialIndex: 0);
//Screens for each nav items.
List<Widget> _NavScreens() {
return [
HomeScreen(),
const Text("History"),
];
}
List<PersistentBottomNavBarItem> _navBarsItems() {
return [
PersistentBottomNavBarItem(
icon: Icon(FluentSystemIcons.ic_fluent_home_regular),
title: "Home",
activeColorPrimary: Colors.blueGrey,
),
PersistentBottomNavBarItem(
icon: Icon(Icons.favorite),
title: ("History"),
activeColorPrimary: CupertinoColors.activeGreen,
),
];
}
#override
Widget build(BuildContext context) {
return Center(
child: PersistentTabView(
controller: _controller,
screens: _NavScreens(),
items: _navBarsItems(),
confineInSafeArea: true,
backgroundColor: Colors.white,
handleAndroidBackButtonPress: true,
resizeToAvoidBottomInset: true,
hideNavigationBarWhenKeyboardShows: true,
decoration: NavBarDecoration(
borderRadius: BorderRadius.circular(10.0),
),
popAllScreensOnTapOfSelectedTab: true,
navBarStyle: NavBarStyle.style9,
),
);
}
This is the original bottom bar that I want to keep fixed in all screens
class _BottomBarState extends State<BottomBar> {
int _selectedIndex = 0;
static final List<Widget> _widgetOptions = <Widget>[
HomeScreen(),
const Text("History"),
];
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
//print('Tapped index is: ${_selectedIndex}');
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: _widgetOptions[_selectedIndex],
),
bottomNavigationBar: Column(
mainAxisSize: MainAxisSize.min,
children: [
BottomNavigationBar(
currentIndex: _selectedIndex,
onTap: _onItemTapped,
...............................
items: const [
BottomNavigationBarItem(
icon: Icon(FluentSystemIcons.ic_fluent_home_regular),
label: "Home"),
BottomNavigationBarItem(
icon: Icon(FluentSystemIcons.ic_fluent_history_regular),
label: "History"),
],),],),);}}
How to apply presistent bottom bar to my project without changing the design? Why am I reciving this error and how to fix it.
persistent_bottom_nav_bar.dart
import 'package:flutter/material.dart';
import 'bottom_nav_bar.dart';
class MyPersistentBottomNavBar extends StatelessWidget {
const MyPersistentBottomNavBar({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Persistent Bottom Nav Bar',
debugShowCheckedModeBanner: false,
theme: ThemeData(primarySwatch: Colors.deepPurple),
home: const BottomNavBar(),
);
}
}
bottom_nav_bar.dart :
import 'package:flutter/material.dart';
import 'package:persistent_bottom_nav_bar_v2/persistent-tab-view.dart';
import 'pages/home_page.dart';
import 'pages/explore_page.dart';
import 'pages/add_page.dart';
import 'pages/inbox_page.dart';
import 'pages/shopping_page.dart';
class BottomNavBar extends StatelessWidget {
const BottomNavBar({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
PersistentTabController controller;
controller = PersistentTabController(initialIndex: 0);
List<Widget> _buildScreens() {
return [
const HomePage(),
const ExplorePage(),
const AddPage(),
const InboxPage(),
const ShoppingPage(),
];
}
List<PersistentBottomNavBarItem> _navBarsItems() {
return [
PersistentBottomNavBarItem(
icon: const Icon(Icons.home),
title: ("Home"),
activeColorPrimary: Colors.deepPurple,
inactiveColorPrimary: Colors.grey,
),
PersistentBottomNavBarItem(
icon: const Icon(Icons.explore),
title: ("Explore"),
activeColorPrimary: Colors.deepPurple,
inactiveColorPrimary: Colors.grey,
),
PersistentBottomNavBarItem(
icon: const Icon(Icons.add, color: Colors.white),
activeColorPrimary: Colors.deepPurple,
inactiveColorPrimary: Colors.grey,
),
PersistentBottomNavBarItem(
icon: const Icon(Icons.email),
title: ("Inbox"),
activeColorPrimary: Colors.deepPurple,
inactiveColorPrimary: Colors.grey,
),
PersistentBottomNavBarItem(
icon: const Icon(Icons.shopping_bag),
title: ("Shop"),
activeColorPrimary: Colors.deepPurple,
inactiveColorPrimary: Colors.grey,
),
];
}
return PersistentTabView(
context,
controller: controller,
screens: _buildScreens(),
items: _navBarsItems(),
confineInSafeArea: true,
backgroundColor: Colors.white, // Default is Colors.white.
handleAndroidBackButtonPress: true, // Default is true.
resizeToAvoidBottomInset:
true, // This needs to be true if you want to move up the screen when keyboard appears. Default is true.
stateManagement: true, // Default is true.
hideNavigationBarWhenKeyboardShows:
true, // Recommended to set 'resizeToAvoidBottomInset' as true while using this argument. Default is true.
decoration: NavBarDecoration(
borderRadius: BorderRadius.circular(10.0),
colorBehindNavBar: Colors.white,
),
popAllScreensOnTapOfSelectedTab: true,
popActionScreens: PopActionScreensType.all,
itemAnimationProperties: const ItemAnimationProperties(
// Navigation Bar's items animation properties.
duration: Duration(milliseconds: 200),
curve: Curves.ease,
),
screenTransitionAnimation: const ScreenTransitionAnimation(
// Screen transition animation on change of selected tab.
animateTabTransition: true,
curve: Curves.ease,
duration: Duration(milliseconds: 200),
),
navBarStyle:
NavBarStyle.style15, // Choose the nav bar style with this property.
);
}
}
Please see code for other pages from the GitHub URL below:
https://github.com/md-siam/package_of_the_day/tree/master/lib/51_persistent_bottom_nav_bar/pages
I have tried this code.It runs fine, can you please try?
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:minawill/ui/home/home.dart';
class BottomBar extends StatefulWidget {
const BottomBar({Key? key}) : super(key: key);
#override
State<BottomBar> createState() => _BottomBarState();
}
class _BottomBarState extends State<BottomBar> {
int _selectedIndex = 0;
static final List<Widget> _widgetOptions = <Widget>[
HomeScreen(),
const Text("History"),
];
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
//print('Tapped index is: ${_selectedIndex}');
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: _widgetOptions[_selectedIndex],
),
bottomNavigationBar: Column(
mainAxisSize: MainAxisSize.min,
children: [
BottomNavigationBar(
currentIndex: _selectedIndex,
onTap: _onItemTapped,
items: const [
BottomNavigationBarItem(
icon: Icon(Icons.add),
label: "Home"),
BottomNavigationBarItem(
icon: Icon(Icons.phone),
label: "History"),
],),],),);}
}
i have added a photo of my output.Please check
so, I am working on my ButtomNavigationBar which should include a rectangle for the icon in the center. I have already archived that. However, now I am facing one problems:
Sadly the shape and icon itself is not clickable. Nothing happens when I click on it (even when I try printing something to the console). It only switches the screen when clicking slightly outside of the shape. For me this seems like a "z-index" problem. Any idea on how I can solve this?
I also have tried to wrap my Container into a GestureDetector but that also does not work..
BottomNavigationBarItem(
icon: GestureDetector(
onTap: () => { onClicked },
child:
Container(
// same code as below
),
),
label: 'Add',
),
This is my complete code:
BottomNavigation
class BottomNavigation extends StatelessWidget {
int selectedIndex;
ValueChanged<int> onClicked;
BottomNavigation({Key? key, required this.selectedIndex, required this.onClicked}) : super(key: key);
#override
Widget build(BuildContext context) {
return BottomNavigationBar(
currentIndex: selectedIndex,
selectedItemColor: AppColors.orange,
onTap: onClicked,
type: BottomNavigationBarType.fixed,
showSelectedLabels: false,
showUnselectedLabels: false,
backgroundColor: AppColors.white,
items: <BottomNavigationBarItem>[
const BottomNavigationBarItem(
icon: Icon(CupertinoIcons.home),
label: 'Home',
),
const BottomNavigationBarItem(
icon: Icon(CupertinoIcons.search),
label: 'Search',
),
BottomNavigationBarItem(
icon: Container(
decoration: BoxDecoration(
color: AppColors.orange,
shape: BoxShape.circle,
),
child: Padding(
padding: const EdgeInsets.all(0.0),
child: IconButton(
onPressed: () => { onClicked },
icon: Icon(CupertinoIcons.plus, color: AppColors.white)
)
),
),
label: 'Add',
),
const BottomNavigationBarItem(
icon: Icon(CupertinoIcons.bell),
label: 'Notifications',
),
const BottomNavigationBarItem(
icon: Icon(CupertinoIcons.news),
label: 'Blog',
),
],
);
}
}
Home (where the BottomNavigation gets integrated):
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
int _selectedIndex = 0;
final screens = [
HomePage(),
SearchPage(),
ProductSubmitPage(),
NotificationPage(),
BlogPage()
];
void onClicked(int index) {
setState(() {
_selectedIndex = index;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: screens[_selectedIndex],
bottomNavigationBar: BottomNavigation(
selectedIndex: _selectedIndex,
onClicked: onClicked,
)
);
}
}
This stack inspired my on how to add a shape to the icon: https://stackoverflow.com/a/67577496/9445999
UPDATE:
Here is my dartpad: https://dartpad.dev/?id=c42f306078c7ece655816482c5c0d413
Kind regards
Your error is on the calling of your function.
You should be doing this like either one of this lines:
//Being 2 the index of this in the list
onPressed: () => onClicked(2),
onPressed: () {onClicked(2);},
I have no experience with this BottomNavigationBarItem so I don't know why it's behaving this way, but that would solve your problem.
I am using footer menu to navigate som page aside the main home page which already has AppBar with a title, I want it to be overridden.
I want it, if I navigate from Home page to meditation page, I want the menu to overridden to "MEDITATION".
Here's my footer menu:
class Footer extends StatefulWidget {
// Footer({Key? key}) : super(key: key);
#override
_FooterState createState() => _FooterState();
}
class _FooterState extends State<Footer> {
var _selectedIndex = 0;
final pages = [
Dashboard(),
Health(),
Meditation(),
Sleep(),
Sounds(),
];
#override
void initState() {
super.initState();
_selectedIndex = 0;
}
#override
Widget build(BuildContext context) {
// return GestureDetector(
return Scaffold(
bottomNavigationBar: Container(
decoration: BoxDecoration(boxShadow: [
BoxShadow(
color: dbShadowColor,
offset: Offset.fromDirection(3, 1),
spreadRadius: 1,
blurRadius: 5)
]),
child: Db5BottomNavigationBar(
items: <Db5BottomNavigationBarItem>[
Db5BottomNavigationBarItem(icon: db5_ic_home),
Db5BottomNavigationBarItem(icon: db5_ic_heart),
Db5BottomNavigationBarItem(icon: db5_ic_meditate),
Db5BottomNavigationBarItem(icon: db5_ic_sleep),
Db5BottomNavigationBarItem(icon: db5_ic_sounds),
],
currentIndex: _selectedIndex,
unselectedIconTheme: IconThemeData(color: db5_icon_color, size: 24),
selectedIconTheme: IconThemeData(color: db5_colorPrimary, size: 24),
onTap: (int index) {
setState(() {
_selectedIndex = index;
});
},
type: Db5BottomNavigationBarType.fixed,
),
),
body: SafeArea(
child: pages[_selectedIndex],
),
);
// );
}
}
Here's my Meditation Page code:
class Meditation extends StatefulWidget {
Meditation({Key? key}) : super(key: key);
#override
_MeditationState createState() => _MeditationState();
}
class _MeditationState extends State<Meditation> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
elevation: 0.0,
backgroundColor: appStore.scaffoldBackground,
centerTitle: true,
title: Text(
"Meditate",
textAlign: TextAlign.center,
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.white,
fontSize: 20,
),
)),
body: Container(
alignment: Alignment.topLeft,
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: EdgeInsets.only(),
child: text(
meditation_text_title,
),
)
],
),
),
),
);
}
}
This is how I rendered my footer on the main HOME PAGE:
return Scaffold(
appBar: AppBar(
backgroundColor: db5_white,
iconTheme: IconThemeData(color: sh_textColorPrimary),
actions: <Widget>[
IconButton(
icon: Icon(Icons.search),
onPressed: () {},
),
],
title: text(title,
textColor: sh_colorPrimary,
fontFamily: fontBold,
fontSize: textSizeNormal),
),
body: Stack(
children: <Widget>[
Dashboard(),
Footer(),
],
),
);
Am I doing it wrongly?
Here's how you should implement your screens.
// Name the class whatever you like
class ScreensController extends StatefulWidget {
const ScreensController({Key? key}) : super(key: key);
#override
_ScreensControllerState createState() => _ScreensControllerState();
}
class _ScreensControllerState extends State<ScreensController> {
int _selectedIndex = 0;
List<String> mainScreensTitles = [
'Dashboard',
'Health',
'Meditation',
'Sleep',
'Sounds'
];
List<Widget> screens= [
Dashboard(),
Health(),
Meditation(),
Sleep(),
Sounds(),
];
#override
Widget build(BuildContext context) {
return Scaffold(
// Indexed stack is used to prevent page rebuilds when navigating between the
//screens
body: IndexedStack(
index: _selectedIndex,
children: screens,
),
bottomNavigationBar: BottomNavigationBar(
//Toggle these booleans if needed
showSelectedLabels: false,
showUnselectedLabels: false,
onTap: (newScreenIndex) {
setState(() {
_selectedIndex = newScreenIndex;
});
},
items: [
BottomNavigationBarItem(
icon: Icon(Icons.home_outlined),
label: mainScreensTitles[0],
),
BottomNavigationBarItem(
icon: Icon(Icons.favorite_outline),
label: mainScreensTitles[1],
),
BottomNavigationBarItem(
icon: Icon(Icons.person_outline),
label: mainScreensTitles[2],
),
BottomNavigationBarItem(
icon: Icon(Icons.person_outline),
label: mainScreensTitles[3],
),
BottomNavigationBarItem(
icon: Icon(Icons.person_outline),
label: mainScreensTitles[4],
),
],
currentIndex: _selectedIndex,
),
);
}
}
Implementation of some of your screens:
Dashboard & Meditation:
class Dashboard extends StatelessWidget {
const Dashboard({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Dashboard'),
),
body: Center(child: Text('Dashboard coming soon')),
);
}
}
class Meditation extends StatelessWidget {
const Meditation({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Meditation'),
),
body: Center(child: Text('Meditation coming soon')),
);
}
}
I am working on a flutter application where I need to redirect to the first screen on BottomNavigationBar when the user presses back from any other screen of the remaining BottomNavigationBar screens. For now, I have added redirecting event on a simple button, will replace this on _onWillPop event.
Please find the code below:
class HomeScreen extends StatefulWidget {
#override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
final PageStorageBucket bucket = PageStorageBucket();
Widget currentScreen = HomeFragment();
int currentTab = 0;
static int selectedIndexN = 0;
static const TextStyle optionStyle = TextStyle(fontSize: 30, fontWeight: FontWeight.bold);
List<Widget> _widgetOptions1 = <Widget>[
HomeFragment(),
LoginFargment(),
SignUpFargment(),
ProfileFargment(),
];
void changeTabMethod(int index) {
print('changeTabMethod is called');
setState(() {
selectedIndexN = index;
});
print('changeTabMethod is called : selectedIndexN : $selectedIndexN');
}
#override
Widget build(BuildContext context) {
return Scaffold(
// return GetBuilder<DashboardController>(
body: Center(
child: _widgetOptions1.elementAt(selectedIndexN),
),
bottomNavigationBar: BottomNavigationBar(
type: BottomNavigationBarType.fixed,
currentIndex: selectedIndexN,
onTap: changeTabMethod,
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(Icons.business),
label: 'Login',
),
BottomNavigationBarItem(
icon: Icon(Icons.school),
label: 'SignUp',
),
BottomNavigationBarItem(
icon: Icon(Icons.school),
label: 'Profile',
),
],
),
);
}
}
Profile screen code:
class ProfileFargment extends StatefulWidget {
#override
_ProfileFragmentState createState() => _ProfileFragmentState();
}
class _ProfileFragmentState extends State<ProfileFargment> {
#override
Widget build(BuildContext context) {
return Scaffold(
body:SafeArea(
child: Container(
padding: EdgeInsets.all(20.0),
height: double.infinity,
width: double.infinity,
color: Colors.teal,
child: GestureDetector(
onTap: () {
//Calling method changeTabMethod(0)
HomeScreen().createState().changeTabMethod(0);
},
child: Container(
margin: EdgeInsets.only(top: 20.0),
height: 40.0,
width: 150.0,
color: Colors.white,
child: Center(child: Text('Profile'),),
),
),
),
),
);
}
}
On the other hand, when I call changeTabMethod from a ProfileFragment screen, it will enter into changeTabMethod but couldn't execute the setState method. So my tab is not changing.
You can consider this console report:
changeTabMethod is called is only printed the second print after setState was not executed.
Can you please let me know what or where I am doing anything wrong?
Thanks in advance :-)
Try below code. By passing function as parameter you can trigger function on home page from any other page.
Home screen code:
class HomeScreen extends StatefulWidget {
#override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
final PageStorageBucket bucket = PageStorageBucket();
// Widget currentScreen = HomeFragment();
int currentTab = 0;
static int selectedIndexN = 0;
static const TextStyle optionStyle =
TextStyle(fontSize: 30, fontWeight: FontWeight.bold);
Widget _widgetOptions1(int index) {
switch (index) {
case 0:
return ProfileFargment(onButtonPressed: changeTabMethod);
case 1:
return Container(child: Text("Page - 2 "));
case 2:
return Container(child: Text("Page - 3 "));
default:
return Container();
}
}
void changeTabMethod(int index) {
print('changeTabMethod is called');
setState(() {
selectedIndexN = index;
});
print('changeTabMethod is called : selectedIndexN : $selectedIndexN');
}
#override
Widget build(BuildContext context) {
return Scaffold(
// return GetBuilder<DashboardController>(
body: Center(
child: _widgetOptions1(selectedIndexN),
),
bottomNavigationBar: BottomNavigationBar(
type: BottomNavigationBarType.fixed,
currentIndex: selectedIndexN,
onTap: changeTabMethod,
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(Icons.business),
label: 'Login',
),
BottomNavigationBarItem(
icon: Icon(Icons.school),
label: 'SignUp',
),
BottomNavigationBarItem(
icon: Icon(Icons.school),
label: 'Profile',
),
],
),
);
}
}
Profile screen code:
class ProfileFargment extends StatefulWidget {
final void Function(int) onButtonPressed;
const ProfileFargment({Key key, this.onButtonPressed});
#override
_ProfileFragmentState createState() => _ProfileFragmentState();
}
class _ProfileFragmentState extends State<ProfileFargment> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Container(
padding: EdgeInsets.all(20.0),
height: double.infinity,
width: double.infinity,
color: Colors.teal,
child: GestureDetector(
onTap: () {
//Calling method changeTabMethod(0)
// HomeScreen().createState().changeTabMethod(0);
widget.onButtonPressed(0);
},
child: Container(
margin: EdgeInsets.only(top: 20.0),
height: 40.0,
width: 150.0,
color: Colors.white,
child: Center(
child: Text('Profile'),
),
),
),
),
),
);
}
}
This is actually quite simple, you just need to pass the function off to the child widget.
So your ProfileFragment will take a variable called changeTab of type Function(int):
Function(int) changeTab;
ProfileFragment(this.changeType); // Constructor
You pass that off when you create the widget inside the _HomeScreenState:
List<Widget> _widgetOptions1 = <Widget>[
…
ProfileFargment(changeTabMethod),
];
Then you can call the function directly in the _ProfileFragmentState:
onTap: () => widget.changeTab(0);
I work on flutter and I make an app with 5 tabs, using a BottomNavigationBar, who change the currently displayed content.
When I tap on a tab, the content updates to the new content, but the tabs icon doesn't change.
I have tried to change the BottomNavigationBarType but that changes nothing...
here is base page widget:
class Home extends StatefulWidget {
Home({Key key}) : super(key: key);
#override
_Home createState() => _Home();
}
class _Home extends State<Home> {
int _selectedIndex = 0;
static List<Widget> _widgetOptions = <Widget>[
HomePage(),
CreateTrain(),
];
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
});
}
#override
Widget build(BuildContext context) {
print(_selectedIndex);
return Scaffold(
body: _widgetOptions.elementAt(_selectedIndex),
bottomNavigationBar: BottomNavigationBar(
currentIndex: 0, // this will be set when a new tab is tapped
items: [
BottomNavigationBarItem(
icon: new Icon(Icons.home),
title: new Text('Home'),
),
BottomNavigationBarItem(
icon: new Icon(Icons.assignment),
title: new Text('Training'),
),
BottomNavigationBarItem(
icon: new Icon(Icons.play_arrow),
title: new Text('start'),
),
BottomNavigationBarItem(
icon: new Icon(Icons.insert_chart),
title: new Text('Stats'),
),
BottomNavigationBarItem(
icon: Icon(Icons.person), title: Text('Profile'))
],
selectedFontSize: 12,
unselectedFontSize: 12,
selectedItemColor: Colors.amber[800],
unselectedItemColor: Colors.grey[500],
showUnselectedLabels: true,
type: BottomNavigationBarType.fixed,
onTap: _onItemTapped,
),
);
}
}
Here is HomePage widget:
class HomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
automaticallyImplyLeading: true,
title: const Text(
'Home',
style: TextStyle(
color: Colors.black,
fontSize: 30,
),
),
backgroundColor: _bgColor,
),
body: Text('data'),
);
}
}
Thanks for your help.
In your code
currentIndex: 0, // this will be set when a new tab is tapped
This should be
currentIndex: _selectedIndex, // this will be set when a new tab is tapped