【问题标题】:Error : LateInitializationError: Field '_startDate@934496985' has not been initialized and Set State错误:LateInitializationError:字段“_startDate@934496985”尚未初始化并设置状态
【发布时间】:2021-10-08 13:37:09
【问题描述】:

我正在通过同步融合日历在颤振应用程序上构建日历,我收到一个错误消息,告诉我“字段''尚未初始化”。我知道我需要初始化 _startDate 和 _endDate 但我不确定应该赋予它什么值。

代码:

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;
late DateTime _startDate;
late TimeOfDay _startTime;
late DateTime _endDate;
late TimeOfDay _endTime;
bool _isAllDay = false;
String _subject = '';
String _notes = '';

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);
    // initialize _startDate and _endDate here? 
    _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.push<Widget>(
                  context,
                  MaterialPageRoute(
                      builder: (BuildContext 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,
      onTap: calendarTapCallback,
      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(() {});
  }

  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 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;
}

除此之外,当我转到另一个页面并返回此日历页面时,之前保存在该页面上的任何事件都已经消失了。

我应该赋予什么值来初始化 _startDate 和 _endDate 以及如何保存页面的状态?

【问题讨论】:

  • 将您的 startDate 和 endDate 更改为 DateTime? _startDate; DateTime? _endDate;
  • 嗨,我是在初始化状态还是在 EventCalendarState 类中声明它?我在 EventCalendarState 类中声明了它,但我得到了无法无条件访问属性“”的错误,因为接收者可以在 void onCalendarTapped() 中为“null”。然后加上“!”。也到这些属性,我再次收到初始化错误。

标签: flutter dart calendar syncfusion


【解决方案1】:

所有状态属性都必须在State 类中声明。 late 表示该变量稍后会被初始化(例如在initState 方法中)。如果初始化时间未知,则使变量可为空,即使用问号作为类型(例如DateTime?

【讨论】:

  • 嗨,我在 EventCalendarState 类中声明了它,但我收到了一个错误,即无法无条件访问属性“”,因为接收者可以在 void onCalendarTapped() 中为“null”。然后加上“!”。到那些属性,我收到相同的尚未初始化错误。
【解决方案2】:

您不初始化startend 日期,以便能够接受空使用?

这样

DateTime? _startDate;
DateTime? _endDate;

【讨论】:

  • 嗨,我在 EventCalendarState 中声明了它,但我得到了一个错误,即属性 '' 不能无条件访问,因为接收者可以为 "_startDate.hour" 等在 void onCalendarTapped 中为 'null' ()。添加 ”!。”到这些属性,但我收到相同的初始化错误。
  • 所以_startDate!.hour! ?
  • 到目前为止,它是:_startTime = TimeOfDay(hour: _startDate!.hour, minute: _startDate!.minute); _endTime = TimeOfDay(hour: _endDate!.hour, minute: _endDate!.minute); 但如果我把'!'在 .hour 之后,它告诉我“!”将无效,因为接收者不能为空。
  • 对于 _startDate!.hour! ,错误是“'!'将无效,因为接收者不能为空。请尝试删除“!”。
  • 不是这个) 好的,尝试使用late 并将DateTime.now() 放在你的startDate 和endDate 中,并删除!,你会得到什么?
【解决方案3】:

您可以使用 DateTime 使它们为空吗?在使用它们之前,如果您想从它们访问小时属性时遇到错误,您可以检查它们是否为空,如下所示:

if([_startTime, _endTime].contains(null)) return;

此外,由于您不使用处理程序之外的数据并且在更改值后使用它,因此您可以使用 DateTime.now() 对其进行初始化,如下所示:

DateTime _startDate = DateTime.now();

你可以这样做:

if (_calendarView == CalendarView.month) {
  _calendarView = CalendarView.day;
  return;
} 

删除后面的 else。

【讨论】:

  • 嘿,我试图添加 if([_startTime, _endTime].contains(null)) return; 但我收到一个错误,它需要一个类成员、一个标识符和 )。
  • 然后尝试:if(_startTime == null || _endTime == null) return;
  • 我仍然遇到同样的错误。为了清楚起见,我应该将条件放在 EventCalendarState 类中,就在 @override 和 initState 之前?
【解决方案4】:

在将变量指定为可为空时,我们需要在使用它们之前设置值,在这种情况下,AppointmentEditor 类使用了 _startDate_endDate 初始化它们之前的值,因此要使用这些值,我们必须确保这些值是用值设置的,因此在导航到编辑器页面之前,我们必须为 startDate 和 endDate 变量设置所需的值,在这种情况下,您可以使用从 CalendarController 中选择的日期值或当前日期时间值,或您要在日历中添加事件的日期时间值。

在此共享代码 sn-p 中,我们将两个变量的当前时间值用作默认值,请在 onPressed 回调中设置 _startDate_endDate FloatingActionButton 的。请在附件中找到相同的代码 sn-p。

代码 sn-p:

onPressed: () {
_startDate??=DateTime.now();
_endDate??=DateTime.now();
 Navigator.push<Widget>(
  context,
  MaterialPageRoute(
      builder: (BuildContext context) => AppointmentEditor()),
)
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-07-27
    • 2021-10-27
    • 2021-12-29
    • 2022-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多