问题描述
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(),];
...
这很奇怪,因为如果我将实际用户的电子邮件地址作为硬编码字符串传递到FavouritesScreen()
中,则代码可以正常工作。但这不能正常工作。
有什么想法吗?
于20/10/20更新:
有关更多上下文,这是build
的代码:
@override
Widget build(BuildContext context) {
List<Widget> _widgetoptions() {
return [
RecipeBlog(),ProperHomeScreen(),];
}
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,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,color: Colors.redAccent),]),BottomNavigationBarItem(
icon: Stack(children: <Widget>[
Icon(Icons.person),showProfileNotificationBadge != false
? Positioned(
top: 0.0,],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),);
}
}
解决方法
该错误指出您不能在初始化程序中使用实例成员。这意味着您不能使用另一个实例变量来初始化实例变量。
一个简单的例子:
class Test {
String initial = "this thing";
String other = initial;//This leads to the same error that you have
}
这是因为初始化程序在构造函数之前执行。这意味着在初始化时无法访问this
,而在访问实例成员时会隐式调用。在对值进行硬编码时,this
不再需要初始化变量,因此它可以工作。
在前面的示例中,调用initial
实际上是在进行this.initial
,但是this
不可用,因此将不起作用。
一种解决方法是将_widgetOptions
的初始化更改为initState
。
但是,首先建议不要尝试执行问题中显示的内容。除可能非常特殊的情况外,Widget
不应存储在变量中。这是因为,当您更新要传递给窗口小部件的参数时,窗口小部件对象本身将不会更新,因此在重建时不会看到任何可视更改。
请改为使_widgetOptions
为您在build
中调用的函数,该函数返回List
中的Widget
个,以便每次创建新Widget
对象时,函数称为:
List<Widget> _widgetOptions() {
return [
RecipeBlog(),FavouritesScreen(userEmail: userEmail,),ProperHomeScreen(),ProfileScreen(),];
}
此方法还从根本上消除了您收到的当前错误,无需进行任何额外的工作,因为在构造函数创建this
之前无法调用该方法。