Flutter 2.0.2 Null 检查运算符用于空值
Posted
技术标签:
【中文标题】Flutter 2.0.2 Null 检查运算符用于空值【英文标题】:Flutter 2.0.2 Null check operator used on a null value 【发布时间】:2021-06-17 02:09:26 【问题描述】:虽然我知道这可能看起来像是重复的,有多少关于此错误的不同帖子,但我收到此错误是因为(我假设)是四个不同屏幕上的不同原因。
我的应用程序启动,但每当我尝试导航我的应用程序时,我最终都会收到红屏错误,因为它说屏幕中的一个小部件在空值上使用了空值检查运算符。
这是我得到的错误:
在构建 NotificationBanner(dirty) 时引发了以下 _CastError: 用于空值的空值检查运算符。 相关的导致错误的小部件是: NotificationBanner file:///Users/alexm/carebloom-flutter/lib/Views/homeview.dart:9:7
在构建 AlertBanner(dirty) 时引发了以下 _CastError: 用于空值的空值检查运算符。 相关的导致错误的小部件是: AlertBanner file:///Users/alexm/carebloom-flutter/lib/Views/alerts_view.dart:57:15
在构建 MessageOverView(dirty) 时引发了以下 _CastError: 用于空值的空值检查运算符。 相关的导致错误的小部件是: MessageOverView file:///Users/alexm/carebloom-flutter/lib/widgets/navbar.dart:41:16
这个有点不一样
在构建 SettingsView(dirty, dependencies: [_EffectiveTickerMode],状态:_SettingsViewState#ddb1e(代码:跟踪 1 个代码)): 用于空值的空值检查运算符。 相关的导致错误的小部件是: SettingsView file:///Users/alexm/carebloom-flutter/lib/widgets/navbar.dart:49:16
现在我假设错误位于作为 WidgetName(dirty) 返回的任何小部件中。所以每一个的代码都在下面。但是,我还想在所有这些之上提出一些问题,以更好地理解并帮助我在未来诊断问题。当它具有 WidgetName(dirty) 时,这究竟意味着什么是 (dity)?除了显示特定小部件的错误消息外,它还提供“相关的导致错误的小部件路径,是我应该查看的路径吗?
通知横幅:
@override
Widget build(BuildContext context)
return StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance
.collection('alerts')
.where('access',
arrayContains: FirebaseAuth.instance.currentUser!.uid)
.where('read', isEqualTo: false)
//.orderBy('createdAt', descending: true)
.snapshots(),
builder: (context, snapshot)
if (!snapshot.hasData || snapshot.data!.docs.length <= 0)
return Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10),
topRight: Radius.circular(10),
bottomLeft: Radius.circular(10),
bottomRight: Radius.circular(10)),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.5),
spreadRadius: 5,
blurRadius: 7,
offset: Offset(0, 3), // changes position of shadow
),
],
),
height: 60.0,
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
children: [
SizedBox(width: 10.0),
Icon(
Icons.check_box,
color: Colors.green,
size: MediaQuery.of(context).size.width * .1,
),
SizedBox(width: 5.0),
Expanded(
child: AutoSizeText(
"No Current Messages or Alerts",
maxLines: 1,
maxFontSize: 20,
style:
TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
),
//if (snapshot.hasData) SizedBox(width: 45),
],
),
);
Alert alert = Alert.fromFirestore(snapshot.data!.docs.first);
return Card(
//height: 60.0,
child: InkWell(
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
children: [
SizedBox(width: 10.0),
Icon(
Icons.warning,
color: Colors.red,
size: MediaQuery.of(context).size.width * .1,
),
SizedBox(width: 15.0),
Expanded(
child: AutoSizeText(
"New Alert for Your Patient",
maxLines: 1,
maxFontSize: 20,
style: TextStyle(
fontSize: 20, fontWeight: FontWeight.bold),
),
),
//if (snapshot.hasData) SizedBox(width: 45),
if (snapshot.hasData) Icon(Icons.arrow_right, size: 50)
],
),
onTap: () ),
elevation: 12,
);
);
Widget getIcon(snapshot)
if (snapshot.hasData)
return Icon(
Icons.warning,
color: Colors.red,
size: 60,
);
else
return Icon(
Icons.check_box,
color: Colors.green,
size: 60,
);
警报横幅:
import 'package:carebloom/models/alert_model.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
class AlertBanner extends StatelessWidget
@override
Widget build(BuildContext context)
return StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance
.collection('alerts')
.where('access',
arrayContains: FirebaseAuth.instance.currentUser!.uid)
.where('read', isEqualTo: false)
.orderBy('createdAt', descending: true)
.snapshots(),
builder: (context, snapshot)
print(snapshot.hasData);
print('alert has error');
print(snapshot.hasError);
if (snapshot.hasError)
print(snapshot.error);
if (!snapshot.hasData || snapshot.data!.docs.length <= 0)
return Card(
child: SizedBox(
height: MediaQuery.of(context).size.height * .08,
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
children: [
SizedBox(width: 10.0),
Icon(
Icons.check_box,
color: Colors.green,
size: MediaQuery.of(context).size.width * .1,
),
SizedBox(width: 5.0),
Expanded(
child: AutoSizeText(
"No Current Messages or Alerts",
maxLines: 1,
maxFontSize: 20,
style: TextStyle(
fontSize: 20, fontWeight: FontWeight.bold),
),
),
//if (snapshot.hasData) SizedBox(width: 45),
],
),
),
);
Alert curAlert = Alert.fromFirestore(snapshot.data!.docs.elementAt(0));
return Card(
child: SizedBox(
height: MediaQuery.of(context).size.height * .08,
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
children: [
SizedBox(width: 10.0),
Icon(
Icons.warning_rounded,
color: Colors.red,
size: MediaQuery.of(context).size.width * .1,
),
SizedBox(width: MediaQuery.of(context).size.width * .08),
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
AutoSizeText(
curAlert.desc!.toLowerCase().capitalizeFirstofEach,
maxLines: 1,
maxFontSize: 20,
style: TextStyle(
fontSize: 20, fontWeight: FontWeight.bold)),
AutoSizeText(
curAlert.fname + ' ' + '$curAlert.lname[0]' + '.',
maxLines: 1,
maxFontSize: 20,
style: TextStyle(
fontSize: 18,
),
),
],
),
Spacer(), //SizedBox(width: MediaQuery.of(context).size.width * .1),
Icon(Icons.arrow_right, size: 50)
//if (snapshot.hasData) SizedBox(width: 45),
],
),
),
);
);
extension StringFormatExtension on String
String get capitalizeFirstofEach => this
.split(" ")
.map((str) => str[0].toUpperCase() + str.substring(1))
.join(" ");
MessageOverView:
import 'package:auto_size_text/auto_size_text.dart';
import 'package:carebloom/Services/auth.dart';
import 'package:carebloom/models/last_message_model.dart';
import 'package:carebloom/models/converstaions.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:intl/intl.dart';
class MessageOverView extends StatelessWidget
// This widget is the root of your application.
final AuthService _auth = AuthService();
@override
Widget build(BuildContext context)
return new Scaffold(
appBar: new AppBar(
centerTitle: true,
automaticallyImplyLeading: false,
backgroundColor: Color(0xFF6cc5de),
title: AutoSizeText(
'Messages',
maxLines: 1,
style: GoogleFonts.raleway(
fontWeight: FontWeight.bold,
fontSize: 35,
textStyle: TextStyle(
color: Colors.black,
)),
textAlign: TextAlign.center,
),
),
body: Container(
padding: EdgeInsets.all(2.5),
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topRight,
end: Alignment.bottomCenter,
colors: [Color(0xFFb5e2ee), Colors.white])),
child: Container(
child: StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance
.collection('messages')
.where('access',
arrayContains: FirebaseAuth.instance.currentUser!.uid)
//FirebaseAuth.instance.currentUser.uid, isEqualTo: true)
.snapshots(),
builder: (context, snapshot)
if (!snapshot.hasData)
return Container();
print("after message list query*****************************");
print(snapshot.data!.docs.toString());
print(snapshot.data!.docs.length);
return ListView.builder(
itemCount: 1,
itemBuilder: (context, pos)
LastMessage msg = LastMessage.fromFirestore(
snapshot.data!.docs.elementAt(pos));
print('error before or after??????/');
print(snapshot.data!.docs.contains(msg.id));
return ConversationList(
patient: msg.fname! + ' ' + msg.lname!,
name: msg.author,
messageText: msg.text,
imageUrl: msg.photoURL,
time: DateFormat('MMM d, h:mma')
.format(msg.msgRecieved!.toDate()),
isMessageRead: false,
pos: pos,
id: msg.id,
);
);
),
),
),
);
设置视图:
import 'dart:io';
import 'package:carebloom/Screens/login.dart';
import 'package:carebloom/Services/auth.dart';
import 'package:carebloom/Services/image_picker_handler.dart';
import 'package:carebloom/models/user.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
class SettingsView extends StatefulWidget
SettingsView(Key? key) : super(key: key);
@override
_SettingsViewState createState() => _SettingsViewState();
class _SettingsViewState extends State<SettingsView>
with TickerProviderStateMixin, ImagePickerListener
// This widget is the root of your application.
final AuthService _auth = AuthService();
File? _image;
AnimationController? _controller;
late ImagePickerHandler imagePicker;
@override
void initState()
super.initState();
_controller = new AnimationController(
vsync: this,
duration: const Duration(milliseconds: 500),
);
imagePicker = new ImagePickerHandler(this, _controller);
imagePicker.init();
@override
void dispose()
_controller!.dispose();
super.dispose();
@override
Widget build(BuildContext context)
print('Before query settings');
return Stack(children: [
StreamBuilder<DocumentSnapshot>(
stream: FirebaseFirestore.instance
.collection('users')
.doc(FirebaseAuth.instance.currentUser!.uid)
.get()
.asStream(),
builder: (context, snapshot)
if (!snapshot.hasData)
return Container();
LUser user = LUser.fromFirestore(snapshot.data!);
return Column(
children: [
Container(
width: double.infinity,
child: Center(
child: CircleAvatar(
backgroundColor: Colors.white,
//backgroundImage: NetworkImage(user.photo),
foregroundColor: Colors.grey[600],
child: null == user.photo
? CircleAvatar(
child: Icon(
Icons.person,
size: 210,
color: Colors.grey[600],
),
backgroundColor: Colors.white,
radius: 110,
)
: CircleAvatar(
backgroundImage: NetworkImage(user.photo!),
backgroundColor: Colors.white,
radius: 110,
),
radius: 110,
),
),
),
ElevatedButton(
onPressed: () => imagePicker.showDialog(context),
child: Icon(Icons.camera_alt_outlined),
style: ElevatedButton.styleFrom(
primary: Color(0xFF3E8094),
onPrimary: Colors.white,
shadowColor: Color(0xFF6cc5de),
elevation: 5,
padding: EdgeInsets.fromLTRB(5, 5, 5, 5),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0),
side: BorderSide(color: Color(0xFF6CC5DE))),
),
),
Container(
width: double.infinity,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(
height: 20,
),
Text(
'Name: ' + user.fname! + ' ' + user.lname!,
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
),
),
SizedBox(
height: 20,
),
Text(
'Email: ' + user.email!,
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
),
),
SizedBox(
height: 20,
),
],
),
),
Container(
width: double.infinity,
height: 50,
child: ElevatedButton(
child: Text('Sign Out'),
style: ElevatedButton.styleFrom(
primary: Color(0xFF3E8094),
onPrimary: Colors.white,
shadowColor: Color(0xFF6cc5de),
elevation: 5,
padding: EdgeInsets.fromLTRB(5, 5, 5, 5),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0),
side: BorderSide(color: Color(0xFF6CC5DE))),
),
onPressed: () async
await _auth.signOut();
Navigator.of(context).push(MaterialPageRoute(
builder: (_) => LoginScreen(),
fullscreenDialog: true));
//
),
),
],
);
),
]);
@override
userImage(File? _image)
setState(()
this._image = _image;
);
到目前为止,我已经检查了所有有空检查但无法修复的内容。 我已经将颤振升级到 2.0.2,运行颤振 pub 缓存修复,并通过两次确保这些事情正确完成。我不确定我错过了什么,但我认为它实际上在代码中。
【问题讨论】:
是的,引用文件的引用行号应该为您提供每个错误来自何处的线索。 【参考方案1】:对我帖子的评论帮助我确认了在哪里寻找我的问题!
这对于我后来遇到的另一个错误很有用。
由于这个问题,它最终在 Firebase 中具有与我们实际使用的数据布局相比旧的数据布局。 firebase 中的几乎一个文档都缺少一个字段,这导致空检查运算符完成它的工作,并让我知道它收到了一个空值。
【讨论】:
您能进一步解释一下吗?哪里缺少什么字段? 当然!我在颤振中的代码正在寻找要显示的特定字段,并且 firebase 中有一些对象缺少一两个字段,因此它给了我一个错误。我进入 firebase 并将字段添加到对象并重新启动我的应用程序,它运行良好。这对我正在做的事情更具体一点,而不是对任何有这个问题的人的包罗万象。我认为我的用户对象缺少导致此问题的性别字段,但它可能是其他人的其他字段。【参考方案2】:问题:
此错误通常发生在使用 Bang !
运算符(也称为空断言运算符)来抛弃可空性时。
例如:
int? i;
void main()
print(i!.isEven); // Runtime error: Null check operator used on a null value
解决方案:
当您不确定类型的可空性时,建议使用局部变量并对其进行空值检查,而不是使用 bang 运算符。
int? i;
void main()
var local = i;
if (local != null)
print(local.isEven);
如果类型为null
,您也可以使用?.
并提供默认值。
int? i;
void main()
print(i?.isEven ?? true);
【讨论】:
局部变量是我要走的路以上是关于Flutter 2.0.2 Null 检查运算符用于空值的主要内容,如果未能解决你的问题,请参考以下文章
Flutter Bloc Test:空值检查运算符用于空值(空安全)
为啥我在 Flutter 测试期间使用 rootBundle.load 得到“对空值使用空检查运算符”?