The above error message is being displayed in my code. Please see below:
class BottomNaviBar extends StatefulWidget {
static const String id = 'bottom_navi_bar';
@override
_BottomNaviBarState createState() => _BottomNaviBarState();
}
class _BottomNaviBarState extends State<BottomNaviBar> {
int selectedIndex = 0;
bool showRecipeNotificationBadge = false;
bool showProfileNotificationBadge = false;
final _auth = FirebaseAuth.instance;
FirebaseUser loggedInUser;
String userEmail;
@override
void initState() {
super.initState();
getCurrentUser();
}
void getCurrentUser() async {
try {
final user = await _auth.currentUser();
if (user != null) {
loggedInUser = user;
userEmail = user.email;
}
} catch (e) {
print(e);
}
}
List<Widget> _widgetOptions = <Widget>[
RecipeBlog(),
FavouritesScreen(userEmail: userEmail,), //this is what is causing the error
ProperHomeScreen(),
ProfileScreen(),
];
...
Its strange, because if I pass an actual user's email address into the FavouritesScreen()
as a hard-coded string, the code works perfectly. But it doesn't work otherwise.
Any ideas?
UPDATED ON 02/10/20:
For more context, here's the code for build
:
@override
Widget build(BuildContext context) {
List<Widget> _widgetOptions() {
return [
RecipeBlog(),
FavouritesScreen(userEmail: userEmail,),
ProperHomeScreen(),
ProfileScreen(),
];
}
return Scaffold(
body: Center(
child: _widgetOptions.elementAt(selectedIndex),
),
bottomNavigationBar: Theme(
data: Theme.of(context).copyWith(
// sets the background color of the `BottomNavigationBar`
canvasColor: Color(0xFF150A42),
// sets the active color of the `BottomNavigationBar` if `Brightness` is light
),
child: BottomNavigationBar(
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.search),
title: Container(),
),
BottomNavigationBarItem(
icon: Icon(Icons.favorite, color: Colors.redAccent,),
title: Container(),
),
BottomNavigationBarItem(
icon: Stack(children: <Widget>[
Icon(Icons.forum),
showRecipeNotificationBadge != false
? Positioned(
top: 0.0,
right: 0.0,
child: Icon(Icons.brightness_1,
size: 12.0, color: Color(0x00000000)),
)
: Positioned(
top: 0.0,
right: 0.0,
child: Icon(Icons.brightness_1,
size: 12.0, color: Colors.redAccent),
),
]),
title: Container(),
),
BottomNavigationBarItem(
icon: Stack(children: <Widget>[
Icon(Icons.person),
showProfileNotificationBadge != false
? Positioned(
top: 0.0,
right: 0.0,
child: Icon(Icons.brightness_1,
size: 12.0, color: Color(0x00000000)),
)
: Positioned(
top: 0.0,
right: 0.0,
child: Icon(Icons.brightness_1,
size: 12.0, color: Colors.redAccent),
),
]),
title: Container(),
),
],
currentIndex: selectedIndex,
selectedItemColor: Color(0xFF150A42),
backgroundColor: Colors.white,
unselectedItemColor: Colors.black38,
onTap: _onItemTapped,
type: BottomNavigationBarType.fixed,
),
),
floatingActionButton: selectedIndex == 0 ? null : FloatingActionButton(
backgroundColor: Color(0xff02aab0),
onPressed: () {Navigator.push(
context,
MaterialPageRoute(builder: (context) => BottomNaviBar()),
);},
child: Icon(Icons.search),
),
);
}
}
The error states that you cannot use instance members in initializers. This means that you cannot use another instance variable to initialize an instance variable.
A simple example:
class Test {
String initial = "this thing";
String other = initial;//This leads to the same error that you have
}
This is because initializers are executed before the constructor. This means there is no way to access this
at initialization time, which is called implicitly when you access instance members. When you hardcode a value, this
is no longer necessary to initialize the variable so it works.
With the previous example, calling initial
is really doing this.initial
, but this
is not available, so it will not work.
A workaround would be to change the initialization of _widgetOptions
to initState
.
However, trying to do what you show in your question is not advisable in the first place. Widget
s shouldn't be stored in variables except for maybe very special cases. This is because when you update the parameters you want to pass to a widget, the widget object itself will not update so no visual changes will be seen on a rebuild.
Instead make _widgetOptions
a function that you call in build
that returns your List
of Widget
s so that new Widget
objects are created every time the function is called:
List<Widget> _widgetOptions() {
return [
RecipeBlog(),
FavouritesScreen(userEmail: userEmail,),
ProperHomeScreen(),
ProfileScreen(),
];
}
This method also inherently removes the current error you're receiving with no extra work as the method can't be called before the constructor creates this
.