无法在初始化程序中访问实例成员 '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


但是,首先不建议尝试按照您在问题中显示的内容进行操作。 Widgets 不应存储在变量中,除非是非常特殊的情况。这是因为当您更新要传递给小部件的参数时,小部件对象本身不会更新,因此在重建时不会看到任何视觉变化。

而是使 _widgetOptions 成为您在 build 中调用的函数,该函数 returns 您的 WidgetList 以便新的 Widget每次调用函数时都会创建对象:

List<Widget> _widgetOptions() {
  return [
    RecipeBlog(),
    FavouritesScreen(userEmail: userEmail,),
    ProperHomeScreen(),
    ProfileScreen(),
  ];
}

由于在构造函数创建 this.

之前无法调用该方法,因此该方法还可以自动消除您收到的当前错误,无需额外工作