LateInitializationError: поле _startDate@934496985 не было инициализировано
Я создаю календарь с помощью календаря syncfusion в приложении flutter, и я получаю сообщение об ошибке, которое сообщает мне, что «Поле '_startDate@934496985'» не было инициализировано.
class EventCalendarState extends State<EventCalendar> {
EventCalendarState();
CalendarView _calendarView = CalendarView.month;
late List<String> eventNameCollection;
late List<Meeting> appointments;
@override
void initState() {
_calendarView = CalendarView.month;
appointments = getMeetingDetails();
_events = DataSource(appointments);
_selectedAppointment = null;
_selectedColorIndex = 0;
_subject = '';
_notes = '';
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
drawer: UserDrawer(),
appBar: AppBar(
iconTheme: IconThemeData(color: Colors.black),
backgroundColor: Colors.transparent,
elevation: 0,
centerTitle: true,
title: const Text('Itinerary',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.w500,
color: Colors.black)),
),
resizeToAvoidBottomInset: false,
body: Padding(
padding: const EdgeInsets.fromLTRB(5, 0, 5, 5),
child: getEventCalendar(_calendarView, _events, onCalendarTapped)),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add, color: Colors.white),
backgroundColor: Color(0xFF003893),
onPressed: () => Navigator.of(context).push(MaterialPageRoute(
builder: (context) => EventEditor(),
))));
}
SfCalendar getEventCalendar(
CalendarView _calendarView,
CalendarDataSource _calendarDataSource,
CalendarTapCallback calendarTapCallback) {
return SfCalendar(
view: _calendarView,
backgroundColor: Colors.transparent,
initialSelectedDate: DateTime.now(),
todayHighlightColor: Color(0xFF003893),
selectionDecoration: BoxDecoration(color: Colors.white60),
showNavigationArrow: true,
cellBorderColor: Colors.transparent,
firstDayOfWeek: 1,
allowedViews: [
CalendarView.day,
CalendarView.week,
CalendarView.month,
CalendarView.timelineWeek
],
monthViewSettings: MonthViewSettings(
showAgenda: true,
agendaViewHeight: 250,
appointmentDisplayMode: MonthAppointmentDisplayMode.appointment),
dataSource: _calendarDataSource,
onTap: calendarTapCallback,
initialDisplayDate: DateTime(DateTime.now().year, DateTime.now().month,
DateTime.now().day, 0, 0, 0),
timeSlotViewSettings: TimeSlotViewSettings(
minimumAppointmentDuration: const Duration(minutes: 60)));
}
void onCalendarViewChange(String value) {
if (value == 'Day') {
_calendarView = CalendarView.day;
} else if (value == 'Week') {
_calendarView = CalendarView.week;
} else if (value == 'Month') {
_calendarView = CalendarView.month;
} else if (value == 'Timeline week') {
_calendarView = CalendarView.timelineWeek;
}
setState(() {});
}
void onCalendarTapped(CalendarTapDetails calendarTapDetails) {
if (calendarTapDetails.targetElement != CalendarElement.appointment) {
return;
}
setState(() {
_selectedAppointment = null;
_isAllDay = false;
_selectedColorIndex = 0;
_subject = '';
_notes = '';
if (_calendarView == CalendarView.month) {
_calendarView = CalendarView.day;
} else {
if (calendarTapDetails.appointments != null &&
calendarTapDetails.appointments!.length == 1) {
final Meeting meetingDetails = calendarTapDetails.appointments![0];
_startDate = meetingDetails.from;
_endDate = meetingDetails.to;
_isAllDay = meetingDetails.isAllDay;
_selectedColorIndex =
_colorCollection.indexOf(meetingDetails.background);
_subject = meetingDetails.eventName == '(No title)'
? ''
: meetingDetails.eventName;
_notes = meetingDetails.description;
_selectedAppointment = meetingDetails;
} else {
final DateTime date = calendarTapDetails.date!;
_startDate = date;
_endDate = date.add(const Duration(hours: 1));
}
_startTime =
TimeOfDay(hour: _startDate.hour, minute: _startDate.minute);
_endTime = TimeOfDay(hour: _endDate.hour, minute: _endDate.minute);
Navigator.push<Widget>(
context,
MaterialPageRoute(builder: (BuildContext context) => EventEditor()),
);
}
});
}
List<Meeting> getMeetingDetails() {
final List<Meeting> meetingCollection = <Meeting>[];
eventNameCollection = <String>[];
eventNameCollection.add('');
_colorCollection = <Color>[];
_colorCollection.add(const Color(0xFF3D4FB5));
_colorCollection.add(const Color(0xFF0F8644));
_colorCollection.add(const Color(0xFF8B1FA9));
_colorCollection.add(const Color(0xFFD20100));
_colorCollection.add(const Color(0xFFFC571D));
_colorCollection.add(const Color(0xFF85461E));
_colorCollection.add(const Color(0xFFFF00FF));
_colorCollection.add(const Color(0xFFE47C73));
_colorCollection.add(const Color(0xFF636363));
_colorNames = <String>[];
_colorNames.add('Blue');
_colorNames.add('Green');
_colorNames.add('Purple');
_colorNames.add('Red');
_colorNames.add('Orange');
_colorNames.add('Caramel');
_colorNames.add('Magenta');
_colorNames.add('Peach');
_colorNames.add('Gray');
return meetingCollection;
}
}
class DataSource extends CalendarDataSource {
DataSource(List<Meeting> source) {
appointments = source;
}
@override
bool isAllDay(int index) => appointments![index].isAllDay;
@override
String getSubject(int index) => appointments![index].eventName;
@override
String getNotes(int index) => appointments![index].description;
@override
Color getColor(int index) => appointments![index].background;
@override
DateTime getStartTime(int index) => appointments![index].from;
@override
DateTime getEndTime(int index) => appointments![index].to;
}
Это общий основной код для страницы календаря, и на нем есть плавающая кнопка действия для добавления события. Когда я нажимаю эту кнопку, появляется сообщение о том, что поле «не было инициализировано». Сначала все работало нормально, даже когда я перезагружался и все такое. Но когда я полностью перезапускаю приложение, появляется эта ошибка.
Код для страницы добавления события выглядит следующим образом:
class EventEditorState extends State<EventEditor> {
Widget _getAppointmentEditor(BuildContext context) {
return Container(
color: Colors.white,
child: ListView(
padding: const EdgeInsets.all(12),
children: <Widget>[
ListTile(
contentPadding: const EdgeInsets.fromLTRB(10, 0, 0, 0),
title: TextField(
controller: TextEditingController(text: _subject),
onChanged: (String value) {
_subject = value;
},
keyboardType: TextInputType.multiline,
maxLines: null,
style: TextStyle(
fontSize: 15,
color: Colors.black,
fontWeight: FontWeight.w400),
decoration: InputDecoration(
border: InputBorder.none,
hintText: 'Title',
),
),
),
const Divider(
height: 1.0,
thickness: 1,
),
ListTile(
contentPadding: const EdgeInsets.all(5),
leading: Icon(
Icons.subject,
color: Colors.black87,
),
title: TextField(
controller: TextEditingController(text: _notes),
onChanged: (String value) {
_notes = value;
},
keyboardType: TextInputType.multiline,
maxLines: null,
style: TextStyle(
fontSize: 15,
color: Colors.black87,
fontWeight: FontWeight.w400),
decoration: InputDecoration(
border: InputBorder.none,
hintText: 'Add description',
),
),
),
const Divider(
height: 1.0,
thickness: 1,
),
ListTile(
contentPadding: const EdgeInsets.fromLTRB(10, 15, 20, 2),
title: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('From', style: TextStyle(fontWeight: FontWeight.w500)),
SizedBox(height: 5),
Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Expanded(
flex: 7,
child: GestureDetector(
child: Text(
DateFormat('EEE, MMM dd yyyy')
.format(_startDate),
textAlign: TextAlign.left),
onTap: () async {
final DateTime? date = await showDatePicker(
context: context,
initialDate: _startDate,
firstDate: DateTime(1900),
lastDate: DateTime(2100),
);
if (date != null && date != _startDate) {
setState(() {
final Duration difference =
_endDate.difference(_startDate);
_startDate = DateTime(
date.year,
date.month,
date.day,
_startTime.hour,
_startTime.minute,
0);
_endDate = _startDate.add(difference);
_endTime = TimeOfDay(
hour: _endDate.hour,
minute: _endDate.minute);
});
}
}),
),
Expanded(
flex: 3,
child: _isAllDay
? const Text('')
: GestureDetector(
child: Text(
DateFormat('hh:mm a')
.format(_startDate),
textAlign: TextAlign.right,
),
onTap: () async {
final TimeOfDay? time =
await showTimePicker(
context: context,
initialTime: TimeOfDay(
hour: _startTime.hour,
minute: _startTime.minute));
if (time != null &&
time != _startTime) {
setState(() {
_startTime = time;
final Duration difference =
_endDate.difference(_startDate);
_startDate = DateTime(
_startDate.year,
_startDate.month,
_startDate.day,
_startTime.hour,
_startTime.minute,
0);
_endDate =
_startDate.add(difference);
_endTime = TimeOfDay(
hour: _endDate.hour,
minute: _endDate.minute);
});
}
})),
]),
],
)),
ListTile(
contentPadding: const EdgeInsets.fromLTRB(10, 5, 20, 2),
title: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('To', style: TextStyle(fontWeight: FontWeight.w500)),
SizedBox(height: 5),
Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Expanded(
flex: 7,
child: GestureDetector(
child: Text(
DateFormat('EEE, MMM dd yyyy')
.format(_endDate),
textAlign: TextAlign.left,
),
onTap: () async {
final DateTime? date = await showDatePicker(
context: context,
initialDate: _endDate,
firstDate: DateTime(1900),
lastDate: DateTime(2100),
);
if (date != null && date != _endDate) {
setState(() {
final Duration difference =
_endDate.difference(_startDate);
_endDate = DateTime(
date.year,
date.month,
date.day,
_endTime.hour,
_endTime.minute,
0);
if (_endDate.isBefore(_startDate)) {
_startDate =
_endDate.subtract(difference);
_startTime = TimeOfDay(
hour: _startDate.hour,
minute: _startDate.minute);
}
});
}
}),
),
Expanded(
flex: 3,
child: _isAllDay
? const Text('')
: GestureDetector(
child: Text(
DateFormat('hh:mm a').format(_endDate),
textAlign: TextAlign.right,
),
onTap: () async {
final TimeOfDay? time =
await showTimePicker(
context: context,
initialTime: TimeOfDay(
hour: _endTime.hour,
minute: _endTime.minute));
if (time != null && time != _endTime) {
setState(() {
_endTime = time;
final Duration difference =
_endDate.difference(_startDate);
_endDate = DateTime(
_endDate.year,
_endDate.month,
_endDate.day,
_endTime.hour,
_endTime.minute,
0);
if (_endDate.isBefore(_startDate)) {
_startDate =
_endDate.subtract(difference);
_startTime = TimeOfDay(
hour: _startDate.hour,
minute: _startDate.minute);
}
});
}
})),
]),
],
)),
SizedBox(height: 10),
ListTile(
contentPadding: const EdgeInsets.fromLTRB(10, 5, 20, 2),
leading: Icon(
Icons.access_time,
color: Colors.black54,
),
title: Row(children: <Widget>[
const Expanded(
child: Text('All-day'),
),
Expanded(
child: Align(
alignment: Alignment.centerRight,
child: Switch(
value: _isAllDay,
onChanged: (bool value) {
setState(() {
_isAllDay = value;
});
},
))),
])),
const Divider(
height: 1.0,
thickness: 1,
),
ListTile(
contentPadding: const EdgeInsets.fromLTRB(10, 5, 20, 2),
leading: Icon(Icons.lens,
color: _colorCollection[_selectedColorIndex]),
title: Text(
_colorNames[_selectedColorIndex],
),
onTap: () {
showDialog<Widget>(
context: context,
barrierDismissible: true,
builder: (BuildContext context) {
return _ColorPicker();
},
).then((dynamic value) => setState(() {}));
},
),
const Divider(
height: 1.0,
thickness: 1,
),
],
));
}
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
appBar: AppBar(
title: Text(getTile()),
backgroundColor: _colorCollection[_selectedColorIndex],
leading: IconButton(
icon: const Icon(
Icons.close,
color: Colors.white,
),
onPressed: () {
Navigator.pop(context);
},
),
actions: <Widget>[
IconButton(
padding: const EdgeInsets.fromLTRB(5, 0, 5, 0),
icon: const Icon(
Icons.done,
color: Colors.white,
),
onPressed: () {
final List<Meeting> meetings = <Meeting>[];
if (_selectedAppointment != null) {
_events.appointments!.removeAt(_events.appointments!
.indexOf(_selectedAppointment));
_events.notifyListeners(CalendarDataSourceAction.remove,
<Meeting>[]..add(_selectedAppointment!));
}
meetings.add(Meeting(
from: _startDate,
to: _endDate,
background: _colorCollection[_selectedColorIndex],
description: _notes,
isAllDay: _isAllDay,
eventName: _subject == '' ? '(No title)' : _subject,
));
_events.appointments!.add(meetings[0]);
_events.notifyListeners(
CalendarDataSourceAction.add, meetings);
_selectedAppointment = null;
Navigator.pop(context);
})
],
),
body: Padding(
padding: const EdgeInsets.fromLTRB(5, 5, 5, 5),
child: Stack(
children: <Widget>[_getAppointmentEditor(context)],
),
),
floatingActionButton: _selectedAppointment == null
? const Text('')
: FloatingActionButton(
onPressed: () {
if (_selectedAppointment != null) {
_events.appointments!.removeAt(_events.appointments!
.indexOf(_selectedAppointment));
_events.notifyListeners(CalendarDataSourceAction.remove,
<Meeting>[]..add(_selectedAppointment!));
_selectedAppointment = null;
Navigator.pop(context);
}
},
child:
const Icon(Icons.delete_outline, color: Colors.white),
backgroundColor: Colors.red,
)));
}
String getTile() {
return _subject.isEmpty ? 'New event' : 'Event details';
}
}
Где я не инициализировал поле?