I am new to programming and don't know how to solve this issue. I am using the java version of 8 and using Android Studio to make apps with Flutter. I have been making a to-do list app, and a cast error happens when
- I make a new list
- I update a list
- I delete a list
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter ToDo List',
debugShowCheckedModeBanner: false,
theme: ThemeData(
fontFamily: "NanumSquare",
primaryColor: Color(0xFF424874), //primary color
),
home: HomeScreen()
);
}
}
this is the main.dart
the error appears on the Home Screen.
class HomeScreen extends StatefulWidget {
@override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
late Future<List<Note>> _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]);
});
}));
}
}
The error message is as below.
======== 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
====================================================================================================
and this is the 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<AddNoteScreen> {
final _formKey = GlobalKey<FormState>();
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<String> _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: <Widget>[
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: <Widget>[
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()
],
),
)
],
),
),
),
),
);
}
}
I am sorry the code is too long. If you can help me, I will really appreciate it. Thank you!