_CastError 抛出构建 Obx:空检查运算符用于空值

_CastError thrown building Obx : Null check operator used on a null value

我是 flutter/dart 的新人,我正在尝试构建一个带有观察者的应用程序,以便在未完成时重定向用户以进行登录

这是我的代码

class ControlView extends GetWidget<AuthViewModel>{



@override
  Widget build(BuildContext context) {

ControlViewModel ctrlvwmdl = ControlViewModel();

return Obx(() {
  return (Get.find<AuthViewModel>().user == null)
      ? LoginView()
      : GetBuilder<ControlViewModel>(
          builder: (controller) => Scaffold(
            body: controller.currentScreen,
            bottomNavigationBar: bottomNavigationBar(),
    ),
  );
});
}

Widget bottomNavigationBar() {
    return GetBuilder<ControlViewModel>(
      init: ControlViewModel(),
      builder: (controller) =>  BottomNavigationBar(
            items: [
              BottomNavigationBarItem(
                  icon: Icon(Icons.search), label: 'search'.tr),
              BottomNavigationBarItem(
                  icon: Icon(Icons.home_outlined), label: 'reserve'.tr),
              BottomNavigationBarItem(
                  icon: Icon(Icons.add), label: 'Déposer'),
              BottomNavigationBarItem(
                  icon: Icon(Icons.email_outlined), label: 'Messages'),
              BottomNavigationBarItem(
                  icon: Icon(Icons.person_outline), label: 'Profil'),
            ],
            currentIndex: controller.navigatorValue,
            onTap: (index) {
              controller.changeSelectedValue(index);
            },
            //elevation: 0,
            //selectedItemColor: Colors.black,
            type: BottomNavigationBarType.fixed,
            backgroundColor: Colors.yellow,
            iconSize: 20,
          ),
    );
  }    
}

我的AuthViewModelclass在下面

class AuthViewModel extends GetxController {
  FirebaseAuth _auth = FirebaseAuth.instance;
  String? email, password, name;
  Rxn<User> _firebaseUser = Rxn<User>();

  String? get user => _firebaseUser.value?.email;

  @override
  void onInit() {
    // TODO: implement onInit
    super.onInit();
    _firebaseUser.bindStream(_auth.authStateChanges());
  }

  @override
  void onReady() {
    // TODO: implement onReady
    super.onReady();
  }

  @override
  void onClose() {
    // TODO: implement onClose
    super.onClose();
  }

  void googleSignInMethod() async {
    print(">> Google Sign In");
    GoogleSignIn googleSignIn = GoogleSignIn(scopes: ['email']);

    final GoogleSignInAccount? googleUser = await googleSignIn.signIn();
    print(">> google user : $googleUser");

    GoogleSignInAuthentication googleSignInAuthentication =
        await googleUser!.authentication;

    final AuthCredential googleCredential = GoogleAuthProvider.credential(
      idToken: googleSignInAuthentication.idToken,
      accessToken: googleSignInAuthentication.accessToken,
    );

    await _auth.signInWithCredential(googleCredential).then((user) {
      print(">> app user : $user");
    });
  }

  void facebookSignInMethod() async {
    print(">> Facebook Sign In");
    FacebookLogin facebookSignIn = new FacebookLogin();

    final FacebookLoginResult result = await facebookSignIn.logIn(['email']);
    print(">> facebook result : $result");

    switch (result.status) {
      case FacebookLoginStatus.loggedIn:
        final FacebookAccessToken accessToken = result.accessToken;
        final facebookAuthCredential =
            FacebookAuthProvider.credential(accessToken.token);

        await _auth.signInWithCredential(facebookAuthCredential).then((user){
          print(">> app user : $user");
        });
        break;
      case FacebookLoginStatus.cancelledByUser:
        print(">> User cancelled login with FaceBook account");
        break;
      case FacebookLoginStatus.error:
        print(">> Error when login with FaceBook account");
        break;
    }
  }

  void signInWithEmailAndPassword() async {
    try {
      print(">> email $email");
      print(">> password $password");
      await _auth
          .signInWithEmailAndPassword(email: email!, password: password!)
          .then((value) {
        print(">> value $value");
      });
    } catch (err) {
      print(err.toString());
      Get.snackbar(
        'Error login account',
        err.toString(),
        colorText: Colors.black,
        snackPosition: SnackPosition.BOTTOM,
      );
    }
  }
}

这是我的 main.dart

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  runApp(MyApp());
}

class MyApp extends StatelessWidget {

  @override
  Widget build(BuildContext context) {

    return GetMaterialApp(
      title: 'Flutter App',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        appBarTheme: AppBarTheme(
          color: Colors.orange
        ),
      ),
      initialBinding: Binding(),
      home: Scaffold(
        appBar: AppBar(
          title: Text('Training App'),
          centerTitle: true,
          actions: <Widget>[
            IconButton(
              icon: Icon(
                Icons.settings,
                color: Colors.white,
              ),
              onPressed: () {
                debugPrint('Settings button tapped');
              },
            ),
            IconButton(
              icon: Icon(
                Icons.more_horiz,
                color: Colors.white,
              ),
              onPressed: () {
                debugPrint('Menu button tapped');
              },
            )
          ],
        ),
        drawer: SideBar(),
        body: ControlView(),
      ),
      translations: Translate(),
      locale: Locale('fr'), //Default language
      fallbackLocale: Locale('fr'), //Default language in case of error
    );
  }
}

我遇到以下奇怪行为:

Another exception was thrown: Null check operator used on a null value

然后我得到这个丑陋的屏幕:

enter image description here

在没有登出的情况下,我执行了热重载,我得到了同样的错误,另外还有一个新的提示,它说

══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY╞═══════════════════════════════════════════

The following _CastError was thrown building Obx(has builder, state: _ObxState#37426): Null check operator used on a null value

The relevant error-causing widget was: Obx Obx:file:///C:/Users/yoozer/StudioProjects/swim_test/lib/view/control_view.dart:14:12

这里是抛出异常时的堆栈

导致错误的相关小部件是: Obx Obx:file:///C:/Users/yoozer/StudioProjects/swim_test/lib/view/control_view.dart:14:12

When the exception was thrown, this was the stack: #0 GetBuilderState.initState (package:get/get_state_manager/src/simple/get_state.dart:134:40) #1 StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:4805:57) #2 ComponentElement.mount (package:flutter/src/widgets/framework.dart:4638:5) #3 Element.inflateWidget (package:flutter/src/widgets/framework.dart:3673:14) #4 Element.updateChild (package:flutter/src/widgets/framework.dart:3422:20) #5 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4690:16) #6 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4840:11) #7 Element.rebuild (package:flutter/src/widgets/framework.dart:4355:5) #8 StatefulElement.update (package:flutter/src/widgets/framework.dart:4872:5) #9 Element.updateChild (package:flutter/src/widgets/framework.dart:3412:15) #10 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4690:16) #11 GetWidgetCacheElement.performRebuild (package:get/get_state_manager/src/simple/get_widget_cache.dart:35:11) #12 Element.rebuild (package:flutter/src/widgets/framework.dart:4355:5) #13 BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2620:33) #14 WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:882:21) #15 RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:319:5) #16 SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1143:15) #17 SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1080:9) #18 SchedulerBinding.scheduleWarmUpFrame. (package:flutter/src/scheduler/binding.dart:863:7) (elided 4 frames from class _RawReceivePortImpl, class _Timer, and dart:async-patch)

我花了很长时间解决错误并试图了解发生了什么,我在互联网上寻找解决方案、类似问题或深入检查此行为的方法,但我仍然卡住了。

欢迎任何帮助 我将不胜感激

[Null check operator used on a null value] 错误意味着用于检查某个 value/parameter 是否为空的 (!) 在它之前收到了一个空值,因此它执行了它的功能并导致了一个大错误。

我没有你的全部代码,但我认为问题可能是由包含的图片中的两行之一引起的。

如果不是,那么在你使用 Null 检查运算符 (!) 的每个地方,你应该执行以下操作:

  1. 在包含 (!)
  2. 的行的正上方打印值
  3. 确保空值永远不会到达 (!) 运算符,或者添加 检查值是否为 null 并用非 null 值覆盖它或执行一些逻辑或您自己的条件。

最重要的是,不要让任何值在为空时到达空检查运算符(!)。

我终于找到了解决办法。 使用flutter dev tools调试,发现每次报错时Obx((){})内联函数调用的GetBuilder return都没有实例化。 所以我在 build() 方法的顶部创建了一个 GetBuilder 变量,并实例化了它。然后在 Obx((){}) 内联函数中,我将代码修改为 return 我在上面实例化的对象。

这是我在代码中所做的唯一修改,其他类和功能没有改变:

class ControlView extends GetWidget<AuthViewModel>{

  @override
  Widget build(BuildContext context) {

    LoginView loginView = LoginView();
    //ControlViewModel ctrlvwmdl = ControlViewModel();
    GetBuilder<ControlViewModel> getbuilder = GetBuilder<ControlViewModel>(
      init: ControlViewModel(),
      builder: (controller) => Scaffold(
        body: controller.currentScreen,
        bottomNavigationBar: bottomNavigationBar(),
      ),
    );

    print(">> ControlView.build() : new call of the method.");
    return Obx(() {
      return (Get.find<AuthViewModel>().user == null)
          ? loginView
          : getbuilder;
    });
  }
}

我找了更多。 错误来自于我没有为 GetBuilder

填写这个 属性
init: ControlViewModel(),

即使是第一个版本的代码也能解决问题。