将事件添加到 table_calendar
Adding events to table_calendar
我是 flutter/Dart 编程的新手,对下面的代码感到困惑。我没有编写代码,但我想用它在 table_calendar 插件的日历网格上显示事件标记。
class calEvent {
final String title;
const calEvent(this.title);
@override
String toString() => title;
}
/// Example events.
///
/// Using a [LinkedHashMap] is highly recommended if you decide to use a map.
final kEvents = LinkedHashMap<DateTime, List<calEvent>>(
equals: isSameDay,
hashCode: getHashCode,
)..addAll(_kEventSource);
**<<<<<< I think FirestoreService().getEvent() would go here but I don't know how to add it or convert from Stream<List<Event>> to LinkedHashMap<DateTime, List<calEvent>> >>>>>>**
final _kEventSource = Map.fromIterable(List.generate(50, (index) => index),
key: (item) => DateTime.utc(2020, 10, item * 5),
value: (item) => List.generate(
item % 4 + 1, (index) => calEvent('Event $item | ${index + 1}')))
..addAll({
DateTime.now(): [
calEvent('Today\'s Event 1'),
calEvent('Today\'s Event 2'),
],
});
int getHashCode(DateTime key) {
return key.day * 1000000 + key.month * 10000 + key.year;
}
/// Returns a list of [DateTime] objects from [first] to [last], inclusive.
List<DateTime> daysInRange(DateTime first, DateTime last) {
final dayCount = last.difference(first).inDays + 1;
return List.generate(
dayCount,
(index) => DateTime.utc(first.year, first.month, first.day + index),
);
}
final kNow = DateTime.now();
final kFirstDay = DateTime(kNow.year, kNow.month - 3, kNow.day);
final kLastDay = DateTime(kNow.year, kNow.month + 3, kNow.day);
我在另一个页面上创建事件并将它们存储在 Firebase 集合中。我可以将这些事件从集合中提取到 Stream 中,但随后我想根据它们应该发生的日期将它们显示在 table_calendar 网格上。这段代码做得很好,但不是来自 firebase 集合。我想将它实现到我的代码中,但使用代码从 Firebase 集合中提取事件作为源。
我的问题是我不明白 how/where 将我的代码放在 _kEventSource 代码中。我附上了一个包含我的一些代码的文件,这样您就可以看到我在做什么。
非常感谢对此的建议。
这是构建 table_calendar 的代码:
这是构建基本日历框架并在日历网格下方构建事件列表的代码。
class _AppointmentCalendarScreenState extends State<AppointmentCalendarScreen> with TickerProviderStateMixin {
late final ValueNotifier<List<calEvent>> _selectedEvents;
late StreamController<Map<DateTime, List>> _streamController;
CalendarFormat _calendarFormat = CalendarFormat.month;
RangeSelectionMode _rangeSelectionMode = RangeSelectionMode
.toggledOff; // Can be toggled on/off by longpressing a date
List<calEvent> _getEventsForDay(DateTime day) {
// Implementation example
return kEvents[day] ?? [];
}
List<calEvent> _getEventsForRange(DateTime start, DateTime end) {
// Implementation example
final days = daysInRange(start, end);
return [
for (final d in days) ..._getEventsForDay(d),
];
}
void _onDaySelected(DateTime selectedDay, DateTime focusedDay) {
if (!isSameDay(_selectedDay, selectedDay)) {
setState(() {
_selectedDay = selectedDay;
_focusedDay = focusedDay;
_rangeStart = null; // Important to clean those
_rangeEnd = null;
_rangeSelectionMode = RangeSelectionMode.toggledOff;
});
_selectedEvents.value = _getEventsForDay(selectedDay);
}
}
@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( **<<<< I get the events from Firebase here**
stream: **_firestoreService.getEventStream(_selectedDay)**,
builder: (context, AsyncSnapshot <List<Event>> eventsSnapShot) {
if (eventsSnapShot.hasData) {
var doc = eventsSnapShot.data!;
for (int i = 0; i < doc.length; i++ ) {
}
return _buildTableCalendar();
} else {
return CircularProgressIndicator();
}
},
),
const SizedBox(height: 8.0),
],
),
);
}
**This is where the calendar grid is built**
Widget _buildTableCalendar() {
return TableCalendar(
firstDay: kFirstDay,
lastDay: kLastDay,
focusedDay: _selectedDay,
selectedDayPredicate: (day) => isSameDay(_selectedDay, day),
locale: 'en_US',
eventLoader: _getEventsForDay, // **This is important**
//holidays: _holidays,
),
onDaySelected: _onDaySelected,
//onVisibleDaysChanged: _onVisibleDaysChanged,
//onCalendarCreated: _onCalendarCreated,
);
}
这是我用来从 Firebase 集合中获取事件的调用 FirestoreService().getEvent() 的代码:
Stream<List<Event>> getEventStream(DateTime dateTime) async* {
yield* _db.collection('agency').doc(globals.agencyId).collection('event')
.where('eventDate', isGreaterThanOrEqualTo: Timestamp.fromDate(dateTime))
.snapshots().map((snapshot) => snapshot.docs
.map((document) => Event.fromFirestore(document.data()))
.toList());
}
这是事件数据模型:
class Event {
final String? eventName;
//final TimeOfDay eventStartTime;
final DateTime? eventStartTime;
final String? eventDuration;
final DateTime? eventDate;
final String? eventDescription;
final String? agentId;
final String? agencyId;
Event(
{this.eventName,
this.eventStartTime,
this.eventDuration,
this.eventDate,
this.eventDescription,
this.agentId,
this.agencyId});
Map<String, dynamic> toMap() {
return {
'eventName': eventName,
'eventStartTime': eventStartTime,
'eventDuration': eventDuration,
'eventDate': eventDate,
'eventDescription': eventDescription,
'agentId': agentId,
'agencyId': agencyId,
};
}
// pass in a map and get an object back
Event.fromFirestore(Map<String, dynamic> firestore)
: eventName = firestore['eventName'],
eventStartTime = firestore['eventStartTime'].toDate(),
eventDuration = firestore['eventDuration'],
eventDate = firestore['eventDate'].toDate(),
eventDescription = firestore['eventDescription'],
agentId = firestore['agentId'],
agencyId = firestore['agencyId'];
}
在kEvents
之前,你必须再做一个map
。
这些是带有代码片段的步骤。
从 Firebase 获取数据 (List<Event>
)
你已经在这样做了。
我们称之为 snapshot.data
将这些事件映射到 kEventSource
。
Map<DateTime, List<Event>> kEventSource = {};
(snapshot.data).forEach((element) {
kEventSource[DateTime(
element.time.year,
element.time.month,
element.time.day,
)] = kEventSource[DateTime(
element.time.year,
element.time.month,
element.time.day,
)] !=
null
? [
...kEventSource[DateTime(
element.time.year,
element.time.month,
element.time.day,
)],
element
]
: [element];
});
现在我们有一个地图数据结构,其中 dateTime
作为键,当天的事件列表作为值。
示例:
{
"2 July 2021" : [Event1, Event2, ...],
...
}
- 现在
kEvents
已定义。
final kEvents = LinkedHashMap<DateTime, List<Event>>(
equals: isSameDay,
hashCode: getHashCode,
)..addAll(kEventSource);
isSameDay
函数来自包本身。
源代码:
/// Checks if two DateTime objects are the same day.
/// Returns `false` if either of them is null.
bool isSameDay(DateTime? a, DateTime? b) {
if (a == null || b == null) {
return false;
}
return a.year == b.year && a.month == b.month && a.day == b.day;
}
getHashCode
相同。虽然你可以修改它。
源代码:
int getHashCode(DateTime key) {
return key.day * 1000000 + key.month * 10000 + key.year;
}
现在您拥有 KEvents
,因此您可以使用其他功能,例如在范围内选择等。
我鼓励您查看软件包作者提供的示例。
我是 flutter/Dart 编程的新手,对下面的代码感到困惑。我没有编写代码,但我想用它在 table_calendar 插件的日历网格上显示事件标记。
class calEvent {
final String title;
const calEvent(this.title);
@override
String toString() => title;
}
/// Example events.
///
/// Using a [LinkedHashMap] is highly recommended if you decide to use a map.
final kEvents = LinkedHashMap<DateTime, List<calEvent>>(
equals: isSameDay,
hashCode: getHashCode,
)..addAll(_kEventSource);
**<<<<<< I think FirestoreService().getEvent() would go here but I don't know how to add it or convert from Stream<List<Event>> to LinkedHashMap<DateTime, List<calEvent>> >>>>>>**
final _kEventSource = Map.fromIterable(List.generate(50, (index) => index),
key: (item) => DateTime.utc(2020, 10, item * 5),
value: (item) => List.generate(
item % 4 + 1, (index) => calEvent('Event $item | ${index + 1}')))
..addAll({
DateTime.now(): [
calEvent('Today\'s Event 1'),
calEvent('Today\'s Event 2'),
],
});
int getHashCode(DateTime key) {
return key.day * 1000000 + key.month * 10000 + key.year;
}
/// Returns a list of [DateTime] objects from [first] to [last], inclusive.
List<DateTime> daysInRange(DateTime first, DateTime last) {
final dayCount = last.difference(first).inDays + 1;
return List.generate(
dayCount,
(index) => DateTime.utc(first.year, first.month, first.day + index),
);
}
final kNow = DateTime.now();
final kFirstDay = DateTime(kNow.year, kNow.month - 3, kNow.day);
final kLastDay = DateTime(kNow.year, kNow.month + 3, kNow.day);
我在另一个页面上创建事件并将它们存储在 Firebase 集合中。我可以将这些事件从集合中提取到 Stream
我的问题是我不明白 how/where 将我的代码放在 _kEventSource 代码中。我附上了一个包含我的一些代码的文件,这样您就可以看到我在做什么。
非常感谢对此的建议。
这是构建 table_calendar 的代码:
这是构建基本日历框架并在日历网格下方构建事件列表的代码。
class _AppointmentCalendarScreenState extends State<AppointmentCalendarScreen> with TickerProviderStateMixin {
late final ValueNotifier<List<calEvent>> _selectedEvents;
late StreamController<Map<DateTime, List>> _streamController;
CalendarFormat _calendarFormat = CalendarFormat.month;
RangeSelectionMode _rangeSelectionMode = RangeSelectionMode
.toggledOff; // Can be toggled on/off by longpressing a date
List<calEvent> _getEventsForDay(DateTime day) {
// Implementation example
return kEvents[day] ?? [];
}
List<calEvent> _getEventsForRange(DateTime start, DateTime end) {
// Implementation example
final days = daysInRange(start, end);
return [
for (final d in days) ..._getEventsForDay(d),
];
}
void _onDaySelected(DateTime selectedDay, DateTime focusedDay) {
if (!isSameDay(_selectedDay, selectedDay)) {
setState(() {
_selectedDay = selectedDay;
_focusedDay = focusedDay;
_rangeStart = null; // Important to clean those
_rangeEnd = null;
_rangeSelectionMode = RangeSelectionMode.toggledOff;
});
_selectedEvents.value = _getEventsForDay(selectedDay);
}
}
@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( **<<<< I get the events from Firebase here**
stream: **_firestoreService.getEventStream(_selectedDay)**,
builder: (context, AsyncSnapshot <List<Event>> eventsSnapShot) {
if (eventsSnapShot.hasData) {
var doc = eventsSnapShot.data!;
for (int i = 0; i < doc.length; i++ ) {
}
return _buildTableCalendar();
} else {
return CircularProgressIndicator();
}
},
),
const SizedBox(height: 8.0),
],
),
);
}
**This is where the calendar grid is built**
Widget _buildTableCalendar() {
return TableCalendar(
firstDay: kFirstDay,
lastDay: kLastDay,
focusedDay: _selectedDay,
selectedDayPredicate: (day) => isSameDay(_selectedDay, day),
locale: 'en_US',
eventLoader: _getEventsForDay, // **This is important**
//holidays: _holidays,
),
onDaySelected: _onDaySelected,
//onVisibleDaysChanged: _onVisibleDaysChanged,
//onCalendarCreated: _onCalendarCreated,
);
}
这是我用来从 Firebase 集合中获取事件的调用 FirestoreService().getEvent() 的代码:
Stream<List<Event>> getEventStream(DateTime dateTime) async* {
yield* _db.collection('agency').doc(globals.agencyId).collection('event')
.where('eventDate', isGreaterThanOrEqualTo: Timestamp.fromDate(dateTime))
.snapshots().map((snapshot) => snapshot.docs
.map((document) => Event.fromFirestore(document.data()))
.toList());
}
这是事件数据模型:
class Event {
final String? eventName;
//final TimeOfDay eventStartTime;
final DateTime? eventStartTime;
final String? eventDuration;
final DateTime? eventDate;
final String? eventDescription;
final String? agentId;
final String? agencyId;
Event(
{this.eventName,
this.eventStartTime,
this.eventDuration,
this.eventDate,
this.eventDescription,
this.agentId,
this.agencyId});
Map<String, dynamic> toMap() {
return {
'eventName': eventName,
'eventStartTime': eventStartTime,
'eventDuration': eventDuration,
'eventDate': eventDate,
'eventDescription': eventDescription,
'agentId': agentId,
'agencyId': agencyId,
};
}
// pass in a map and get an object back
Event.fromFirestore(Map<String, dynamic> firestore)
: eventName = firestore['eventName'],
eventStartTime = firestore['eventStartTime'].toDate(),
eventDuration = firestore['eventDuration'],
eventDate = firestore['eventDate'].toDate(),
eventDescription = firestore['eventDescription'],
agentId = firestore['agentId'],
agencyId = firestore['agencyId'];
}
在kEvents
之前,你必须再做一个map
。
这些是带有代码片段的步骤。
从 Firebase 获取数据 (
List<Event>
)
你已经在这样做了。
我们称之为snapshot.data
将这些事件映射到
kEventSource
。
Map<DateTime, List<Event>> kEventSource = {};
(snapshot.data).forEach((element) {
kEventSource[DateTime(
element.time.year,
element.time.month,
element.time.day,
)] = kEventSource[DateTime(
element.time.year,
element.time.month,
element.time.day,
)] !=
null
? [
...kEventSource[DateTime(
element.time.year,
element.time.month,
element.time.day,
)],
element
]
: [element];
});
现在我们有一个地图数据结构,其中 dateTime
作为键,当天的事件列表作为值。
示例:
{
"2 July 2021" : [Event1, Event2, ...],
...
}
- 现在
kEvents
已定义。
final kEvents = LinkedHashMap<DateTime, List<Event>>(
equals: isSameDay,
hashCode: getHashCode,
)..addAll(kEventSource);
isSameDay
函数来自包本身。
源代码:
/// Checks if two DateTime objects are the same day.
/// Returns `false` if either of them is null.
bool isSameDay(DateTime? a, DateTime? b) {
if (a == null || b == null) {
return false;
}
return a.year == b.year && a.month == b.month && a.day == b.day;
}
getHashCode
相同。虽然你可以修改它。
源代码:
int getHashCode(DateTime key) {
return key.day * 1000000 + key.month * 10000 + key.year;
}
现在您拥有 KEvents
,因此您可以使用其他功能,例如在范围内选择等。
我鼓励您查看软件包作者提供的示例。