_Cast Error: 在空值上使用了空检查运算符

14 浏览
0 Comments

_Cast Error: 在空值上使用了空检查运算符

我刚开始学编程,不知道如何解决这个问题。

我使用的是Java 8版本,并使用Android Studio和Flutter制作应用程序。

我正在制作一个待办事项列表应用程序,当我:

  • 创建一个新列表
  • 更新一个列表
  • 删除一个列表

时,会发生转换错误。

class MyApp extends StatelessWidget {

@override

Widget build(BuildContext context) {

return MaterialApp(

title: 'Flutter ToDo List',

debugShowCheckedModeBanner: false,

theme: ThemeData(

fontFamily: "NanumSquare",

primaryColor: Color(0xFF424874), //主要颜色

),

home: HomeScreen()

);

}

}

这是main.dart文件。

错误出现在HomeScreen上。

class HomeScreen extends StatefulWidget {

@override

_HomeScreenState createState() => _HomeScreenState();

}

class _HomeScreenState extends State {

late Future> _noteList;

final DateFormat _dateFormatter = DateFormat("MMM dd, yyyy");

DatabaseHelper _databaseHelper = DatabaseHelper.instance;

void initState() {

super.initState();

_updateNoteList();

}

_updateNoteList() {

_noteList = DatabaseHelper.instance.getNoteList();

}

Widget _buildNote(Note note) {

return Padding(

padding: EdgeInsets.symmetric(horizontal: 25),

child: Column(

children: [

Container(

margin: EdgeInsets.all(5),

color: Color(0xFFDCD6F7),

child: ListTile(

title: Text(

note.title!,

style: TextStyle(

fontSize: 20,

color: Color(0xFF424874),

decoration: note.status == 0

? TextDecoration.none

: TextDecoration.lineThrough),

),

subtitle: Text(

"${_dateFormatter.format(note.date!)}-${note.priority}",

style: TextStyle(

fontSize: 15,

color: Color(0xFF424874),

decoration: note.status == 0

? TextDecoration.none

: TextDecoration.lineThrough),

),

trailing: Checkbox(

onChanged: (value) {

note.status = value! ? 1 : 0;

DatabaseHelper.instance.updateNote(note);

_updateNoteList();

Navigator.pushReplacement(

context, MaterialPageRoute(builder: (_) => HomeScreen())

);

},

activeColor: Color(0xFFA6B1E1),

value: note.status == 1 ? true : false,

),

onTap: () => Navigator.push(

context,

CupertinoPageRoute(

builder: (_) => AddNoteScreen(

updateNoteList: _updateNoteList(),

note: note

)

),

),

),

),

Divider(

height: 5,

color: Color(0xFFA6B1E1),

thickness: 2,

)

],

),

);

}

@override

Widget build(BuildContext context) {

return Scaffold(

backgroundColor: Color(0xFFF4EEFF),

floatingActionButton: FloatingActionButton(

backgroundColor: Color(0xFF424874),

onPressed: () {

Navigator.push(

context,

CupertinoPageRoute(

builder: (_) => AddNoteScreen(

updateNoteList: _updateNoteList(),

),

));

},

child: Icon(Icons.add),

),

body: FutureBuilder(

future: _noteList,

builder: (context, AsyncSnapshot snapshot) {

if (!snapshot.hasData) {

return Center(

child: CircularProgressIndicator(),

);

}

final int completedNoteCount = snapshot.data!.where((Note note) => note.status == 1).toList().length;

return ListView.builder(

padding: EdgeInsets.symmetric(vertical: 80),

itemCount: int.parse(snapshot.data!.length.toString()) + 1,

itemBuilder: (BuildContext context, int index) {

if (index == 0) {

return Padding(

padding:

EdgeInsets.symmetric(horizontal: 40, vertical: 20),

child: Column(

crossAxisAlignment: CrossAxisAlignment.start,

children: [

Text(

"My Notes",

style: TextStyle(

color: Color(0xFF424874),

fontSize: 40,

fontWeight: FontWeight.bold),

),

SizedBox(

height: 10,

),

Text(

"$completedNoteCount of ${snapshot.data.length}",

style: TextStyle(

color: Color(0xFFA6B1E1),

fontSize: 20,

fontWeight: FontWeight.w600),

),

],

),

);

}

return _buildNote(snapshot.data![index-1]);

});

}));

}

}

错误信息如下所示。

======== Exception caught by gesture ===============================================================

The following _CastError was thrown while handling a gesture:

Null check operator used on a null value

When the exception was thrown, this was the stack:

#0 _AddNoteScreenState._delete (package:crud_sqlite_app/screens/add_note_screen.dart:80:26)

#1 _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:989:21)

#2 GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:182:24)

#3 TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:607:11)

#4 BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:296:5)

...

Handler: "onTap"

Recognizer: TapGestureRecognizer#e7613

debugOwner: GestureDetector

state: ready

won arena

finalPosition: Offset(150.8, 655.2)

finalLocalPosition: Offset(110.8, 46.2)

button: 1

sent tap down

====================================================================================================

这是add_note_screen.dart文件。

class AddNoteScreen extends StatefulWidget {

final Note? note;

final Function? updateNoteList;

AddNoteScreen({this.note, this.updateNoteList});

@override

_AddNoteScreenState createState() => _AddNoteScreenState();

}

class _AddNoteScreenState extends State {

final _formKey = GlobalKey();

String _title = "";

String _priority = "Low";

String btnText = "Add Note";

String titleText = "Add Note";

DateTime _date = DateTime.now();

TextEditingController _dateController = TextEditingController();

final DateFormat _dateFormatter = DateFormat("MMM dd, yyyy");

final List _priorities = ["Low", "Medium", "High"];

@override

void initState(){

super.initState();

if(widget.note != null) {

_title = widget.note!.title!;

_date = widget.note!.date!;

_priority = widget.note!.priority!;

setState(() {

btnText = "Update Note";

titleText = "Update Note";

});

}

else {

setState(() {

btnText = "Add Note";

titleText = "Add Note";

});

}

_dateController.text = _dateFormatter.format(_date);

}

@override

void dispose() {

_dateController.dispose();

super.dispose();

}

_handleDatePicker() async {

final DateTime? date = await showDatePicker(

context: context,

initialDate: _date,

firstDate: DateTime(2000),

lastDate: DateTime(2100));

if (date != null && date != _date) {

setState(() {

_date = date;

});

_dateController.text = _dateFormatter.format(date);

}

}

_delete() {

DatabaseHelper.instance.deleteNote(widget.note!.id!);

Navigator.pushReplacement(

context,

MaterialPageRoute(

builder: (_)=> HomeScreen()

)

);

widget.updateNoteList!();

}

_submit() {

if (_formKey.currentState!.validate()) {

_formKey.currentState!.save();

print("$_title, $_date, $_priority");

Note note = Note(

title: _title,

date: _date,

priority: _priority

);

if (widget.note == null){

note.status = 0;

DatabaseHelper.instance.insertNote(note);

Navigator.pushReplacement(context, MaterialPageRoute(builder: (_)=> HomeScreen())

);

}

else{

note.id = widget.note!.id;

note.status = widget.note!.status;

DatabaseHelper.instance.updateNote(note);

Navigator.pushReplacement(context, MaterialPageRoute(builder: (_)=> HomeScreen())

);

}

widget.updateNoteList!();

}

}

@override

Widget build(BuildContext context) {

return Scaffold(

backgroundColor: Color(0xFFF4EEFF),

body: GestureDetector(

onTap: () => FocusScope.of(context).unfocus(),

child: SingleChildScrollView(

child: Container(

padding: EdgeInsets.symmetric(horizontal: 40, vertical: 80),

child: Column(

crossAxisAlignment: CrossAxisAlignment.start,

children: [

GestureDetector(

onTap: () => Navigator.pushReplacement(

context,

MaterialPageRoute(

builder: (_) => HomeScreen(),

)

),

child: Icon(

Icons.arrow_back,

size: 30,

color: Color(0xFFA6B1E1),

),

),

SizedBox(

height: 20.0,

),

Text(

titleText,

style: TextStyle(

color: Color(0xFF424874),

fontSize: 40,

fontWeight: FontWeight.bold),

),

SizedBox(

height: 10,

),

Form(

key: _formKey,

child: Column(

children: [

Padding(

padding: EdgeInsets.symmetric(vertical: 20),

child: TextFormField(

style: TextStyle(fontSize: 18),

decoration: InputDecoration(

labelText: "Title",

labelStyle: TextStyle(fontSize: 18),

border: OutlineInputBorder(

borderRadius: BorderRadius.circular(10))),

validator: (input) => input!.trim().isEmpty

? "Please enter a note title"

: null,

onSaved: (input) => _title = input!,

initialValue: _title,

),

),

Padding(

padding: EdgeInsets.symmetric(vertical: 20),

child: TextFormField(

readOnly: true, //hide keyboard

controller: _dateController,

style: TextStyle(fontSize: 18),

onTap: _handleDatePicker,

decoration: InputDecoration(

labelText: "Date",

labelStyle: TextStyle(fontSize: 18),

border: OutlineInputBorder(

borderRadius: BorderRadius.circular(10))),

),

),

Padding(

padding: EdgeInsets.symmetric(vertical: 20),

child: DropdownButtonFormField(

isDense: true,

icon: Icon(Icons.arrow_drop_down_circle),

iconSize: 22,

iconEnabledColor: Color(0xFF424874),

items: _priorities.map((String priority) {

return DropdownMenuItem(

value: priority,

child: Text(

priority,

style: TextStyle(

color: Colors.black,

fontSize: 18,

),

));

}).toList(),

style: TextStyle(fontSize: 18),

decoration: InputDecoration(

labelText: "Priority",

labelStyle: TextStyle(fontSize: 18),

border: OutlineInputBorder(

borderRadius: BorderRadius.circular(10)

)

),

// validator: (input) => _priority == null ? "Please",

onChanged: (value) {

setState(() {

_priority = value.toString();

});

},

value: _priority,

),

),

Container(

margin: EdgeInsets.symmetric(vertical: 20),

height: 60.0,

width: double.infinity,

decoration: BoxDecoration(

borderRadius: BorderRadius.circular(30)),

child: ElevatedButton(

style: ButtonStyle(

backgroundColor: MaterialStateProperty.all(Theme.of(context).primaryColor)

),

child: Text(

btnText,

style: TextStyle(color: Colors.white, fontSize: 20),

),

onPressed: _submit,

),

),

widget.note != null ? Container(

margin: EdgeInsets.symmetric(vertical: 20),

height: 60,

width: double.infinity,

decoration: BoxDecoration(

color: Color(0xFF424874),

borderRadius: BorderRadius.circular(30)

),

child: ElevatedButton(

style: ButtonStyle(

backgroundColor: MaterialStateProperty.all(Theme.of(context).primaryColor)

),

child: Text("Delete Note",

style: TextStyle(

color: Colors.white,

fontSize: 20

),

),

onPressed: _delete,

),

): SizedBox.shrink()

],

),

)

],

),

),

),

),

);

}

}

非常抱歉代码太长了。

如果你能帮助我,我会非常感激。

谢谢!

0
0 Comments

当你在一个未初始化的可空实例上使用感叹号操作符(!)时,就会出现这个错误。这个操作符只应该在你确定变量不会为null时使用,我不建议使用它。请查看这个答案

在Dart和Flutter中,可空类型是非常重要的概念。它们允许我们在变量中存储可能为null的值,并且在使用这些值之前进行空值检查。然而,在使用可空类型时,有时候可能会发生错误。

一个常见的错误是在一个未初始化的可空实例上使用感叹号操作符(!)。这个操作符告诉编译器,你确定这个变量不会为null,因此可以安全地使用它。但是,如果这个变量实际上是null,就会抛出一个_Cast Error : Null check operator used on a null value的错误。

解决这个问题的方法是避免使用感叹号操作符(!)。而是使用安全调用操作符(?.)和空值合并操作符(??)。安全调用操作符允许我们在访问可能为null的值之前进行空值检查,如果变量为null,就会返回null而不是抛出错误。空值合并操作符则允许我们在变量为null时提供一个备选值。

下面是一个示例代码,演示了如何使用安全调用操作符和空值合并操作符来避免_Cast Error : Null check operator used on a null value错误:

String? nullableString;

// 使用安全调用操作符和空值合并操作符

String nonNullString = nullableString?.toUpperCase() ?? "Default Value";

print(nonNullString);

在上面的代码中,我们首先声明了一个可空字符串变量nullableString。然后,我们使用安全调用操作符(?.)和空值合并操作符(??)来将nullableString的值转换为大写。如果nullableString为null,那么nonNullString将被赋值为"Default Value"。

通过使用安全调用操作符和空值合并操作符,我们可以避免_Cast Error : Null check operator used on a null value错误,并且在处理可能为null的值时更加安全和可靠。

总结起来,当你在一个未初始化的可空实例上使用感叹号操作符(!)时,就会出现_Cast Error : Null check operator used on a null value错误。为了避免这个错误,我们应该使用安全调用操作符(?.)和空值合并操作符(??)来进行空值检查和提供备选值。这样可以使我们的代码更加健壮和可靠。

0