无法在初始化程序中访问实例成员 'userEmail'
The instance member 'userEmail' can't be accessed in an initializer
我的代码中显示了以上错误信息。请看下面:
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()
中,代码将完美运行。但否则它不起作用。
有什么想法吗?
更新于 2020 年 2 月 10 日:
有关更多上下文,这是 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),
),
);
}
}
错误指出您不能在初始值设定项中使用实例成员。这意味着您不能使用另一个实例变量来初始化一个实例变量。
一个简单的例子:
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
s 不应存储在变量中,除非是非常特殊的情况。这是因为当您更新要传递给小部件的参数时,小部件对象本身不会更新,因此在重建时不会看到任何视觉变化。
而是使 _widgetOptions
成为您在 build
中调用的函数,该函数 returns 您的 Widget
的 List
以便新的 Widget
每次调用函数时都会创建对象:
List<Widget> _widgetOptions() {
return [
RecipeBlog(),
FavouritesScreen(userEmail: userEmail,),
ProperHomeScreen(),
ProfileScreen(),
];
}
由于在构造函数创建 this
.
之前无法调用该方法,因此该方法还可以自动消除您收到的当前错误,无需额外工作
我的代码中显示了以上错误信息。请看下面:
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()
中,代码将完美运行。但否则它不起作用。
有什么想法吗?
更新于 2020 年 2 月 10 日:
有关更多上下文,这是 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),
),
);
}
}
错误指出您不能在初始值设定项中使用实例成员。这意味着您不能使用另一个实例变量来初始化一个实例变量。
一个简单的例子:
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
s 不应存储在变量中,除非是非常特殊的情况。这是因为当您更新要传递给小部件的参数时,小部件对象本身不会更新,因此在重建时不会看到任何视觉变化。
而是使 _widgetOptions
成为您在 build
中调用的函数,该函数 returns 您的 Widget
的 List
以便新的 Widget
每次调用函数时都会创建对象:
List<Widget> _widgetOptions() {
return [
RecipeBlog(),
FavouritesScreen(userEmail: userEmail,),
ProperHomeScreen(),
ProfileScreen(),
];
}
由于在构造函数创建 this
.