Получение оператора проверки на нуль, используемого при ошибке с нулевым значением

#flutter #dart #calendar #syncfusion

Вопрос:

Я столкнулся с ошибками в своем календаре Syncfusion. Совсем недавно я не смог инициализировать свои переменные _startDate и _endDate, но некоторые люди предложили сделать их недействительными, что я и сделал, но теперь это дает мне ошибку «Оператор проверки Null, используемый для нулевого значения».

Календарный код:

 class EventCalendar extends StatefulWidget {
  const EventCalendar({Key? key}) : super(key: key);

  @override
  EventCalendarState createState() => EventCalendarState();
}

List<Color> _colorCollection = <Color>[];
List<String> _colorNames = <String>[];
int _selectedColorIndex = 0;
late DataSource _events;
Meeting? _selectedAppointment;
DateTime? _startDate;
DateTime? _endDate;
late TimeOfDay _startTime;
late TimeOfDay _endTime;
bool _isAllDay = false;
String _subject = '';
String _notes = '';


class EventCalendarState extends State<EventCalendar> {
  EventCalendarState(); //check

  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)),
        floatingActionButton: FloatingActionButton(
            child: Icon(Icons.add, color: Colors.white),
            backgroundColor: Color(0xFF003893),
            onPressed: () => Navigator.push<Widget>(
                  context,
                  MaterialPageRoute(
                      builder: (BuildContext context) => EventEditor()),
                )));
  }

  SfCalendar getEventCalendar(
    CalendarView _calendarView,
    CalendarDataSource _calendarDataSource,
  ) {
    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,
      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(() {});
  }

  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 Meeting {
  Meeting(
      {required this.from,
      required this.to,
      this.background = Colors.green,
      this.isAllDay = false,
      this.eventName = '',
      this.description = ''});

  final String eventName;
  final DateTime from;
  final DateTime to;
  final Color background;
  final bool isAllDay;
  final String description;
}
 

Добавление/Редактирование/Удаление события в коде календаря:

 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: TextFormField(
                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 amp;amp; 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 amp;amp;
                                            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 amp;amp; 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 amp;amp; 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';
  }
}
 

Как мне решить эту проблему?

Комментарии:

1. На какой линии вы получаете эти ошибки в первый раз?

2. запустите код в vs code, используя параметры «начать отладку», и он приведет вас к точному местоположению переменной, которая вызывает ошибку оператора проверки на нуль, и сообщит нам, где остановится выполнение

3. Он останавливается на Text(DateFormat('EEE, MMM dd yyyy').format(_startDate!), для списка, где пользователь выбирает дату «От» в классе EventEditorState.