【发布时间】:2021-09-15 20:08:16
【问题描述】:
我将我的应用程序迁移到 null-safety。我遇到了一些错误,除了最后一个之外,我都能修复。
此页面是日历页面,发生错误的部分是我在构建日历时。我正在使用 table_calendar 插件。
我添加了“?”在为 _getEventsFroDay() 定义函数类型之后。我不知道这是否是正确的做法。
- 参数类型“列表?无法将 Function(DateTime)' 分配给参数类型 'List Function(DateTime)?'。
这是函数:
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(日期时间天){。
这是完整的 .dart 文件:
// 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;
}
}
}
【问题讨论】:
-
你能告诉我eventLoader的类型吗?
-
@TipuSultan 这里是在 github 中找到的代码中的声明 (github.com/aleksanderwozniak/table_calendar/blob/master/lib/src/…): final List
Function(DateTime day)?事件加载器; -
这是作者在示例中使用此代码的方式: List
_getEventsForDay(DateTime day) { // 实现示例 return kEvents[day] ?? [];但如果我这样做,我会收到此错误:正文可能正常完成,导致返回“null”,但返回类型可能是不可为空的类型 -
请查看我的更新答案
标签: flutter migration dart-null-safety