首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >把我的颤音应用程序迁移到null_safety有一个问题

把我的颤音应用程序迁移到null_safety有一个问题
EN

Stack Overflow用户
提问于 2021-07-04 23:17:07
回答 3查看 209关注 0票数 0

我将我的应用程序迁移到空安全。我犯了一些错误,除了最后一个错误之外,我都能改正。

此页是日历页,错误发生的部分是在构建日历时发生的。我正在使用table_calendar插件。

我加了"?“在定义了_getEventsFroDay()的函数类型之后。我不知道这是不是正确的方法。

参数类型'List? Function(DateTime)‘不能分配给参数类型'List Function(DateTime)?'.’

这是一项功能:

代码语言:javascript
复制
List<dynamic>? _getEventsForDay(DateTime day) {
    // kEvents is a linkedHashMap
    for (int i = 0; i < eventDoc.length; i++ ) {
      DateTime eventDate = eventDoc[i].eventDate;
      DateTime eventDateUTC = eventDate.toUtc();
      if (day.year == eventDate.year && day.day == eventDate.day && day.month == eventDate.month) {
        List<dynamic> eventList = [];
        eventList.add(eventDoc[i].agencyId);
        eventList.add(eventDoc[i].agentId);
        eventList.add(eventDoc[i].eventDate);
        eventList.add(eventDoc[i].eventDescription);
        eventList.add(eventDoc[i].eventDuration);
        eventList.add(eventDoc[i].eventName);
        eventList.add(eventDoc[i].eventStartTime);
        //print('kEvents: $kEvents');
        return kEvents.putIfAbsent(eventDateUTC, () => eventList);
      }
    }
  }

This is where the error is occuring:
Widget _buildTableCalendar() {
    return TableCalendar(
      eventLoader: _getEventsForDay, <<<< ERROR HERE

这是删除"?“之后的错误消息。列表?_getEventsForDay(DateTime day) {。

下面是完整的.dart文件:

代码语言:javascript
复制
// Example holidays
final Map<DateTime, List> _holidays = {
  DateTime(2020, 1, 1): ['New Year\'s Day'],
  DateTime(2020, 1, 6): ['Epiphany'],
  DateTime(2020, 2, 14): ['Valentine\'s Day'],
  DateTime(2020, 4, 21): ['Easter Sunday'],
  DateTime(2020, 4, 22): ['Easter Monday'],
};

final kNow = DateTime.now();
final kFirstDay = DateTime(kNow.year, kNow.month - 3, kNow.day);
final kLastDay = DateTime(kNow.year, kNow.month + 3, kNow.day);

final eventsRef = FirebaseFirestore.instance.collection('agency').doc(globals.agencyId).collection('event');
final _db = FirebaseFirestore.instance;
final _firestoreService = FirestoreService();
bool showSpinner = false;
DateTime? _selectedDay;
DateTime _focusedDay = DateTime.now();
LinkedHashMap<DateTime, List<Event>> kEvents = LinkedHashMap<DateTime, List<Event>>();

class AppointmentCalendarScreen extends StatefulWidget {
  AppointmentCalendarScreen({Key? key, this.title}) : super(key: key);

  final String? title;

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

class _AppointmentCalendarScreenState extends State<AppointmentCalendarScreen> with TickerProviderStateMixin {
  late final ValueNotifier<List<Event>> _selectedEvents;
  Map<DateTime, List>? _selectedEventsMap;
  late StreamController<Map<DateTime, List>> _streamController;
  late var eventDoc;

  @override
  void initState() {
    super.initState();

    _streamController = StreamController();
    _selectedDay = _focusedDay;
    _selectedEvents = ValueNotifier(_getEventsForDay(_selectedDay!));
  }

  @override
  void dispose() {
    _selectedEvents.dispose();
    _streamController.close();

    super.dispose();
  }

  List<Event> _getEventsForDay(DateTime day) {
    // kEvents is a linkedHashMap
    for (int i = 0; i < eventDoc.length; i++ ) {
      DateTime eventDate = eventDoc[i].eventDate;
      DateTime eventDateUTC = eventDate.toUtc();
      if (day.year == eventDate.year && day.day == eventDate.day && day.month == eventDate.month) {
        List<Event> eventList = [];
        eventList.add(eventDoc[i].agencyId);
        eventList.add(eventDoc[i].agentId);
        eventList.add(eventDoc[i].eventDate);
        eventList.add(eventDoc[i].eventDescription);
        eventList.add(eventDoc[i].eventDuration);
        eventList.add(eventDoc[i].eventName);
        eventList.add(eventDoc[i].eventStartTime);
        //print('kEvents: $kEvents');
        return (kEvents.putIfAbsent(eventDateUTC, () => eventList))??[];

      }
    }
  }

  void _onDaySelected(DateTime selectedDay, DateTime focusedDay) {
    if (!isSameDay(_selectedDay, selectedDay)) {
      setState(() {
        _selectedDay = selectedDay;
        _focusedDay = focusedDay;
      });

      _selectedEvents.value = _getEventsForDay(selectedDay);
    }
  }

  void _onVisibleDaysChanged(DateTime first, DateTime last,
      CalendarFormat format) {
  }

  void _onCalendarCreated(DateTime first, DateTime last,
      CalendarFormat format) {
  }

  @override
  Widget build(BuildContext context) {
    final eventProvider = Provider.of<EventProvider>(context);
    FirebaseFirestore _db = FirebaseFirestore.instance;

    return Scaffold(
      appBar: AppBar(
        automaticallyImplyLeading: false,
        title: Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Image.asset('assets/images/Appbar_logo.png',
                fit: BoxFit.cover, height: 56),
          ],
        ),
      ),
      backgroundColor: Colors.white,
      resizeToAvoidBottomInset: false,
      body: Column(
        mainAxisSize: MainAxisSize.max,
        children: <Widget>[
          StreamBuilder(
            stream: _db.collection('agency').doc(globals.agencyId).collection('event')
              .where('eventDate', isGreaterThanOrEqualTo: kFirstDay)
              .where('eventDate', isLessThanOrEqualTo: kLastDay)
                    .snapshots().map((snapshot) => snapshot.docs
              .map((document) => Event.fromFirestore(document.data()))
              .toList()),
            builder: (context, AsyncSnapshot <List<Event>> eventsSnapShot) {
              if (eventsSnapShot.hasData) {

                return _buildTableCalendar();
              } else {
                return CircularProgressIndicator();
              }
            },
          ),
          const SizedBox(height: 8.0),
          //_buildButtons(),
          ElevatedButton(
            onPressed: () async {
              setState(() {
                showSpinner = true;
              });
              try {
                globals.newAgency = true;

                Navigator.of(context).pushReplacement(MaterialPageRoute(
                    builder: (context) => AddEventScreen()));

                setState(() {
                  showSpinner = false;
                });
              } catch (e) {
                // todo: add better error handling
                print(e);
              }
            },
            child: Text('Add Event'),
          ),
          const SizedBox(height: 8.0),
          Expanded(child: _buildEventList()),
        ],
      ),
    );
  }

  // Simple TableCalendar configuration (using Styles)
  Widget _buildTableCalendar() {
    return TableCalendar(
      firstDay: kFirstDay,
      lastDay: kLastDay,
      focusedDay: _focusedDay,
      selectedDayPredicate: (day) => isSameDay(_selectedDay, day),
      locale: 'en_US',
      eventLoader: (day) {
        return _getEventsForDay(day);
      },
      startingDayOfWeek: StartingDayOfWeek.sunday,
      calendarStyle: CalendarStyle(
        isTodayHighlighted: true,
        selectedDecoration: BoxDecoration(color: Colors.deepOrange[400]),
        todayDecoration: BoxDecoration(color: Colors.deepOrange[200]),
        markerDecoration: BoxDecoration(color: Colors.deepPurpleAccent),
        outsideDaysVisible: false,
      ),
      headerStyle: HeaderStyle(
        formatButtonTextStyle:
        TextStyle().copyWith(color: Colors.white, fontSize: 15.0),
        formatButtonDecoration: BoxDecoration(
          color: Colors.deepOrange[400],
          borderRadius: BorderRadius.circular(16.0),
        ),
      ),
      onDaySelected: (selectedDay, focusedDay) {
        setState(() {
          _selectedDay = selectedDay;
          _focusedDay = focusedDay; // update `_focusedDay` here as well
        });
      },
      onPageChanged: (focusedDay) {
        _focusedDay = focusedDay;
      },
    );
  }

  Widget _buildHolidaysMarker() {
    return Icon(
      Icons.add_box,
      size: 20.0,
      color: Colors.blueGrey[800],
    );
  }

  Widget _buildEventList() {
    final _db = FirebaseFirestore.instance;

    return Container(
      child: StreamBuilder<QuerySnapshot>(
        //stream: FirestoreService().getEventStream(_focusedDay),
        stream: _db.collection('agency').doc(globals.agencyId).collection(
            'event').where('eventDate', isEqualTo: _focusedDay).snapshots(),
        builder: (context, snapshot) {
          if (!snapshot.hasData) {
            return Center(
                child: const Text(
                  'Loading...',
                  style: TextStyle(
                      fontSize: 20, fontWeight: FontWeight.bold),
                ));
          } else {
            var doc = snapshot.data!.docs;
            return new ListView.builder(
                itemCount: doc.length,
                itemBuilder: (BuildContext context, int index) {
                  Event _event = Event.fromFirestore(
                      doc[index].data() as Map<String, dynamic>);
                  return ListTile(
                    isThreeLine: true,
                    title: Text(
                      '${_event.eventName ?? 'n/a'}',
                      style: TextStyle(
                          fontWeight: FontWeight.w900,
                          color: Colors.blueAccent),
                    ),
                    subtitle: Text.rich(TextSpan(
                        text:
                        '${DateFormat('EE MM-dd-yyyy').format(_event.eventDate!) ?? 'n/a'}\n'
                        '${DateFormat('h:mm a').format(_event.eventStartTime!) ?? 'n/a'}, '
                        'Duration: ${_event.eventDuration ?? 'n/a'} minutes',
                        children: <TextSpan>[
                          TextSpan(
                            text:
                            '\n${_event.eventDescription ?? 'n/a'}',
                            style: TextStyle(
                                fontWeight: FontWeight.w900,
                                color: Colors.blueGrey),
                          )
                        ])),
                    //trailing: Text('MLS#: ${_event.mlsNumber ?? 'n/a'}'),
                    onTap: () {
                      globals.newTrxn = false;
                      /*
                    Navigator.of(context).push(MaterialPageRoute(
                        builder: (context) =>
                            AddEventScreen(
                                doc[index].data())));

                     */
                    },
                  );
                }
            );
          }
        },

      ),
    );
  }

  Map<DateTime, List>? convertToMap(List<Event> item) {
    Map<DateTime, List>? result;

    for (int i = 0; i < item.length; i++) {
      Event data = item[i];
      //get the date and convert it to a DateTime variable
      //DateTime currentDate = DateFormat('MM-dd-yyyy - kk:mm').format(data.eventDate);
      DateTime currentDate = DateTime(data.eventDate!.year, data.eventDate!.month, data.eventDate!.day, data.eventDate!.hour, data.eventDate!.minute);

      List eventNames = [];
      //add the event name to the the eventNames list for the current date.
      //search for another event with the same date and populate the eventNames List.
      for (int j = 0; j < item.length; j++) {
        //create temp calendarItemData object.
        Event temp = item[j];
        //establish that the temp date is equal to the current date
        if (data.eventDate == temp.eventDate) {
          //add the event name to the event List.
          eventNames.add(temp.eventName);
        } //else continue
      }

      //add the date and the event to the map if the date is not contained in the map
      if (result == null) {
        result = {
          currentDate: eventNames
        };
      } else {
        result[currentDate] = eventNames;
      }
      return result;
    }
  }
}
EN

回答 3

Stack Overflow用户

发布于 2021-07-05 14:48:19

如果您的列表是Event类型,那么您应该从_getEventsForDay函数返回List<Event>?而不是List<dynamic>?。希望这能解决你的问题。

编辑:

是我的错。我已经阅读了文档,它说,您可以给事件加载器的值一个null或者返回类型应该是一个非空列表的函数。

那么,在你的情况下,你是在返回一个列表?这意味着函数返回类型可以为null。这就是你犯错误的原因。

代码语言:javascript
复制
List<Event> _getEventsForDay(DateTime day) {
    // kEvents is a linkedHashMap
    for (int i = 0; i < eventDoc.length; i++ ) {
      DateTime eventDate = eventDoc[i].eventDate;
      DateTime eventDateUTC = eventDate.toUtc();
      if (day.year == eventDate.year && day.day == eventDate.day && day.month == eventDate.month) {
        List<dynamic> eventList = [];
        eventList.add(eventDoc[i].agencyId);
        eventList.add(eventDoc[i].agentId);
        eventList.add(eventDoc[i].eventDate);
        eventList.add(eventDoc[i].eventDescription);
        eventList.add(eventDoc[i].eventDuration);
        eventList.add(eventDoc[i].eventName);
        eventList.add(eventDoc[i].eventStartTime);
        //print('kEvents: $kEvents');
        return kEvents.putIfAbsent(eventDateUTC, () => eventList);
      }
    }
  }

第二个问题:

现在,这个错误表明kEvents.putIfAbsent(eventDateUTC, () => eventList);可能返回null。这是不可接受的,因为我们的函数现在不会返回任何null值。在这种情况下,我们可以像这样使用null check操作符。

return (kEvents.putIfAbsent(eventDateUTC, () => eventList))??[];

希望这能解决你的问题。

票数 1
EN

Stack Overflow用户

发布于 2021-07-05 19:37:00

代码语言:javascript
复制
  List<Event> _getEventsForDay(DateTime day) {
    // kEvents is a linkedHashMap
    for (int i = 0; i < eventDoc.length; i++ ) {
      DateTime eventDate = eventDoc[i].eventDate;
      DateTime eventDateUTC = eventDate.toUtc();
      if (day.year == eventDate.year && day.day == eventDate.day && day.month == eventDate.month) {
        List<dynamic> eventList = [];
        eventList.add(eventDoc[i].agencyId);
        eventList.add(eventDoc[i].agentId);
        eventList.add(eventDoc[i].eventDate);
        eventList.add(eventDoc[i].eventDescription);
        eventList.add(eventDoc[i].eventDuration);
        eventList.add(eventDoc[i].eventName);
        eventList.add(eventDoc[i].eventStartTime);
        //print('kEvents: $kEvents');
        return kEvents.putIfAbsent(eventDateUTC, () => eventList);
      }
    }
  }

由于您的for在其中有一个if子句,而且它可以是空的,所以您的函数有可能永远不会到达返回语句:

代码语言:javascript
复制
return kEvents.putIfAbsent(eventDateUTC, () => eventList);

因此IDE告诉我们的是,您需要在函数的末尾添加一个返回,这样如果eventDoc.length < 1 if 子句永远不会实现,它就可以返回 null。

要解决您的问题,请添加:

代码语言:javascript
复制
return [];

for循环之后,在函数的末尾:

代码语言:javascript
复制
List<Event> _getEventsForDay(DateTime day) {
    // kEvents is a linkedHashMap
    for (int i = 0; i < eventDoc.length; i++ ) {
      DateTime eventDate = eventDoc[i].eventDate;
      DateTime eventDateUTC = eventDate.toUtc();
      if (day.year == eventDate.year && day.day == eventDate.day && day.month == eventDate.month) {
        List<dynamic> eventList = [];
        eventList.add(eventDoc[i].agencyId);
        eventList.add(eventDoc[i].agentId);
        eventList.add(eventDoc[i].eventDate);
        eventList.add(eventDoc[i].eventDescription);
        eventList.add(eventDoc[i].eventDuration);
        eventList.add(eventDoc[i].eventName);
        eventList.add(eventDoc[i].eventStartTime);
        //print('kEvents: $kEvents');
        return kEvents.putIfAbsent(eventDateUTC, () => eventList);
      }
    }

    return [];
  }
票数 0
EN

Stack Overflow用户

发布于 2022-11-10 11:37:07

您可以使用分支的颤振table_calendar与空安全:https://pub.dev/packages/table_calendar_null_safe

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68249429

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档