_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,
),
);
}
}
我的AuthViewModel
class在下面
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
);
}
}
我遇到以下奇怪行为:
- 当我 运行 第一次申请时,一切正常,我可以使用 google 登录方法,Facebook 登录方法以及密码和电子邮件登录在方法中
- 当我要求应用程序注销时,它执行了并且一切正常
- 从那时起,每当我尝试再次登录时,似乎(当然是在故障排除之后)应用程序成功登录了用户,但是在构建 UI 时抛出了下面的异常
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 检查运算符 (!) 的每个地方,你应该执行以下操作:
- 在包含 (!)
的行的正上方打印值
- 确保空值永远不会到达 (!) 运算符,或者添加
检查值是否为 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(),
即使是第一个版本的代码也能解决问题。
我是 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,
),
);
}
}
我的AuthViewModel
class在下面
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
);
}
}
我遇到以下奇怪行为:
- 当我 运行 第一次申请时,一切正常,我可以使用 google 登录方法,Facebook 登录方法以及密码和电子邮件登录在方法中
- 当我要求应用程序注销时,它执行了并且一切正常
- 从那时起,每当我尝试再次登录时,似乎(当然是在故障排除之后)应用程序成功登录了用户,但是在构建 UI 时抛出了下面的异常
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 检查运算符 (!) 的每个地方,你应该执行以下操作:
- 在包含 (!) 的行的正上方打印值
- 确保空值永远不会到达 (!) 运算符,或者添加 检查值是否为 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(),
即使是第一个版本的代码也能解决问题。