虽然我知道这可能看起来像是重复的,有多少关于这个错误的不同帖子,但我收到这个错误是因为(我假设)是四个不同屏幕上的不同原因。
我的应用程序启动,但每当我尝试导航我的应用程序时,我最终都会收到红屏错误,因为它说屏幕中的一个小部件在空值上使用了空值检查运算符。
以下是我得到的错误:
在构建 NotificationBanner(dirty) 时引发了以下 _CastError: Null check operator used on a null value。相关的导致错误的小部件是:NotificationBanner file:///Users/alexm/carebloom-flutter/lib/Views/homeview.dart:9:7
在构建 AlertBanner(dirty) 时引发了以下 _CastError:Null check operator used on a null value。相关的导致错误的小部件是:AlertBanner file:///Users/alexm/carebloom-flutter/lib/Views/alerts_view.dart:57:15
在构建 MessageOverView(dirty) 时引发了以下 _CastError:Null 检查运算符用于空值。相关的导致错误的小部件是:MessageOverView file:///Users/alexm/carebloom-flutter/lib/widgets/navbar.dart:41:16
这个有点不同
在构建 SettingsView(dirty, dependencies: [_EffectiveTickerMode], state: _SettingsViewState#ddb1e(tickers: tracking 1 ticker)) 时抛出了以下 _CastError:空值检查运算符。相关的导致错误的小部件是: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 缓存修复,并通过两次确保这些事情正确完成。我不确定我错过了什么,但我认为它实际上在代码中。