[英]How to display appointment from Firestore in SfCalendar's data source in Flutter?
I try to get appointments from Firestore
to display them in datasource in SfCalendar
.我尝试从
Firestore
获取约会以将它们显示在SfCalendar
的数据源中。
I've tried 2 ways but in both case nothing is displayed.我尝试了 2 种方法,但在这两种情况下都没有显示任何内容。
Here is the code这是代码
Event事件
@JsonSerializable()
class Event {
String uid;
String title;
DateTime from;
DateTime to;
String? comment;
String backgroundColor;
bool isAllDay;
Event({required this.uid, required this.title, required this.from,
required this.to, this.comment, required this.backgroundColor, this.isAllDay = false});
factory Event.fromJson(Map<String, dynamic> json) => _$EventFromJson(json);
Map<String, dynamic> toJson() => _$EventToJson(this);
}
EventDataSource事件数据源
class EventDataSource extends CalendarDataSource {
EventDataSource(List<Event> appointments) {
this.appointments = appointments;
}
Event getEvent(int index) => appointments![index] as Event;
@override
DateTime getStartTime(int index) => getEvent(index).from;
@override
DateTime getEndTime(int index) => getEvent(index).to;
@override
String getSubject(int index) => getEvent(index).title;
@override
Color getColor(int index) => Utils.getColorFromString(getEvent(index).backgroundColor);
@override
bool isAllDay(int index) => getEvent(index).isAllDay;
}
EventViewModel事件视图模型
class EventViewModel extends ChangeNotifier {
final FirebaseFirestore _db = FirebaseFirestore.instance;
final List<Event> _events = [];
DateTime _selectedDate = DateTime.now();
List<Event> get events => _events;
List<Event> get eventsOfSelectedDate => _events;
DateTime get selectedDate => _selectedDate;
void setDate(DateTime date) => _selectedDate = date;
Future createInstructorEvent(Event event) async {
final eventDocument = _db.collection("instructorsEvent")
.doc();
final json = event.toJson();
await eventDocument.set(json);
}
}
CalendarWidget日历小部件
class CalendarWidget extends StatefulWidget {
const CalendarWidget({Key? key}) : super(key: key);
@override
State<CalendarWidget> createState() => _CalendarWidgetState();
}
class _CalendarWidgetState extends State<CalendarWidget> {
@override
Widget build(BuildContext context) {
//final events = Provider.of<EventViewModel>(context).events;
return Scaffold(
body: SfCalendar(
//dataSource: EventDataSource(events),
view: CalendarView.month,
onLongPress: (details) {
final eventViewModel = Provider.of<EventViewModel>(context, listen: false);
eventViewModel.setDate(details.date!);
showModalBottomSheet(
context: context,
builder: (context) => const DailyWidget(),
);
},
),
floatingActionButton: FloatingActionButton(
child: const Icon(
Icons.add,
color: white,
),
onPressed: () {
_clickOnFAB(context);
},
),
);
}
void _clickOnFAB(BuildContext context) {
Utils.goToEventPlanningScreen(context);
}
}
Try #1尝试#1
I've tried what's explained in SfCalendar documentation but it doesn't work.我已经尝试过SfCalendar 文档中解释的内容,但它不起作用。
CalendarWidget日历小部件
class CalendarWidget extends StatefulWidget {
const CalendarWidget({Key? key}) : super(key: key);
@override
State<CalendarWidget> createState() => _CalendarWidgetState();
}
class _CalendarWidgetState extends State<CalendarWidget> {
EventDataSource? events; //--------------------------------------- TODO 1
final FirebaseFirestore _db = FirebaseFirestore.instance; //--------------------------------------- TODO 2
@override
void initState() {
getInstructorEvent().then((results) {
SchedulerBinding.instance.addPostFrameCallback((timeStamp) { //------------------------- TODO 3
setState(() {});
});
});
super.initState();
}
@override
Widget build(BuildContext context) {
//final events = Provider.of<EventViewModel>(context).events;
return Scaffold(
body: SfCalendar(
dataSource: events, //--------------------------------------- TODO 5
//dataSource: EventDataSource(events),
view: CalendarView.month,
onLongPress: (details) {
final eventViewModel = Provider.of<EventViewModel>(context, listen: false);
eventViewModel.setDate(details.date!);
showModalBottomSheet(
context: context,
builder: (context) => const DailyWidget(),
);
},
),
floatingActionButton: FloatingActionButton(
child: const Icon(
Icons.add,
color: white,
),
onPressed: () {
_clickOnFAB(context);
},
),
);
}
void _clickOnFAB(BuildContext context) {
Utils.goToEventPlanningScreen(context);
}
Future getInstructorEvent() async { //--------------------------------------- TODO 4
var snapshot = await _db.collection(instructorsEvent)
.get();
List<Event> eventList = snapshot.docs.map(
(e) => Event(
uid: e.data()["uid"],
title: e.data()["title"],
from: DateFormat('dd/MM/yyyy HH:mm:ss').parse(e.data()['from']),
to: DateFormat('dd/MM/yyyy HH:mm:ss').parse(e.data()['yo']),
comment: e.data()["comment"],
backgroundColor: e.data()["backgroundColor"],
isAllDay: e.data()["isAllDay"],
)
).toList();
setState(() {
events = EventDataSource(eventList);
print("EventDataSource 1: $events");
});
}
}
Try #2尝试#2
EventViewModel事件视图模型
class EventViewModel extends ChangeNotifier {
final FirebaseFirestore _db = FirebaseFirestore.instance;
List<Event> _events = [];
DateTime _selectedDate = DateTime.now();
List<Event> get events => _events;
List<Event> get eventsOfSelectedDate => _events;
DateTime get selectedDate => _selectedDate;
void setDate(DateTime date) => _selectedDate = date;
Future createInstructorEvent(Event event) async {
final eventDocument = _db.collection("instructorsEvent")
.doc();
final json = event.toJson();
await eventDocument.set(json);
}
Future getInstructorEvent() async {
var snapshot = await _db.collection(instructorsEvent)
.get();
List<Event> list = snapshot.docs
.map((e) => Event(
uid: e.data()["uid"],
title: e.data()["title"],
from: DateFormat("dd/MM/yyyy HH:mm:ss").parse(e.data()["from"]),
to: DateFormat("dd/MM/yyyy HH:mm:ss").parse(e.data()["to"]),
comment: e.data()["comment"],
backgroundColor: e.data()["backgroundColor"],
isAllDay: e.data()["isAllDay"],
))
.toList();
}
}
CalendarWidget日历小部件
class _CalendarWidgetState extends State<CalendarWidget> {
Future<dynamic>? futureEvents; //--------------------------------------- TODO 1
@override
void initState() {
futureEvents = _getInstructorEvent(); //--------------------------------------- TODO 2
super.initState();
}
@override
Widget build(BuildContext context) {
//final events = Provider.of<EventViewModel>(context).events;
return Scaffold(
body: sfCalendarMonth(), //--------------------------------------- TODO 5
floatingActionButton: FloatingActionButton(
child: const Icon(
Icons.add,
color: white,
),
onPressed: () {
_clickOnFAB(context);
},
),
);
}
void _clickOnFAB(BuildContext context) {
Utils.goToEventPlanningScreen(context);
}
_getInstructorEvent() async {
final eventListTest = Provider.of<EventViewModel>(context, listen: false); //----------------- TODO 3
eventListTest.getInstructorEvent();
}
Widget sfCalendarMonth() => FutureBuilder(
future: futureEvents,
builder: (context, AsyncSnapshot snapshot) {
if(snapshot.hasData) {
return SfCalendar(
dataSource: snapshot.data, //--------------------------------------- TODO 4
view: CalendarView.month,
onLongPress: (details) {
final eventViewModel = Provider.of<EventViewModel>(context, listen: false);
eventViewModel.setDate(details.date!);
showModalBottomSheet(
context: context,
builder: (context) => const DailyWidget(),
);
},
);
}
return Container();
},
);
}
Try #3尝试#3
EventViewModel事件视图模型
class EventViewModel extends ChangeNotifier {
final FirebaseFirestore _db = FirebaseFirestore.instance;
final List<Event> _events = [];
DateTime _selectedDate = DateTime.now();
Future<dynamic> getInstructorEvent() async {
var snapshot = await _db.collection(instructorsEvent)
.get();
List<Event> list = snapshot.docs
.map((e) => Event(
uid: e.data()["uid"],
title: e.data()["title"],
from: DateFormat("dd-MM-yyyyTHH:mm:ss").parse(e.data()["from"]),
to: DateFormat("dd-MM-yyyyTHH:mm:ss").parse(e.data()["to"]),
comment: e.data()["comment"],
backgroundColor: e.data()["backgroundColor"],
isAllDay: e.data()["isAllDay"],
))
.toList();
print("Appointments in VM: $list"); //------ return [Instance of 'Event']
}
}
CalendarWidget日历小部件
class CalendarWidget extends StatefulWidget {
const CalendarWidget({Key? key}) : super(key: key);
@override
State<CalendarWidget> createState() => _CalendarWidgetState();
}
class _CalendarWidgetState extends State<CalendarWidget> {
Future<dynamic>? _futureEvents; //---------------------------- TODO 1
@override
void initState() { //---------------------------- TODO 2
_futureEvents = _getInstructorEvent();
print("Appointments in initState 0: $_futureEvents"); //--- return Instance of 'Future<dynamic>' 'Future<dynamic>'
super.initState();
}
@override
Widget build(BuildContext context) {
final events = Provider.of<EventViewModel>(context).events;
return Scaffold(
body: sfCalendarMonth(),
floatingActionButton: FloatingActionButton(
child: const Icon(
Icons.add,
color: white,
),
onPressed: () {
_clickOnFAB(context);
},
),
);
}
//****************************************************************************
// Click on FAB
//****************************************************************************
void _clickOnFAB(BuildContext context) {
Utils.goToEventPlanningScreen(context);
}
Future<dynamic> _getInstructorEvent() async {
final eventListTest = Provider.of<EventViewModel>(context, listen: false);
dynamic eventList = await eventListTest.getInstructorEvent();
return eventList; //---------------------------- TODO 3
}
Widget sfCalendarMonth() => FutureBuilder(
future: _futureEvents, //---------------------------- TODO 4
builder: (context, AsyncSnapshot<dynamic> snapshot) {
final event = snapshot.data;
print("Appointments in FutureBuilder 1: $event"); //-- return null
if(snapshot.hasData) {
return SfCalendar(
dataSource: snapshot.data,
view: CalendarView.month,
onLongPress: (details) {
final eventViewModel = Provider.of<EventViewModel>(context, listen: false);
eventViewModel.setDate(details.date!);
showModalBottomSheet(
context: context,
builder: (context) => const DailyWidget(),
);
},
);
}
return const Center(
child: Text(
"Nothing to show",
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
),
),
);
},
);
}
Thanks in advance提前致谢
Problem solved问题解决了
List<Event> events = [];
late Event event;
Widget小部件
Widget sfCalendarMonth() => StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance.collection(instructorsEvent).snapshots(),
builder: (context, snapshot) {
if(snapshot.hasData) {
final eventDocument = snapshot.data!.docs;
events.clear();
for(var e in eventDocument){
final uid = e.get("uid");
final title = e.get("title");
final from = e.get("from");
final to = e.get("to");
final comment = e.get("comment");
final backgroundColor = e.get("backgroundColor");
final isAllDay = e.get("isAllDay");
event = Event(
uid: uid,
title: title,
from: Utils.stringToDateTime(from),
to: Utils.stringToDateTime(to),
comment: comment,
backgroundColor: backgroundColor,
isAllDay: isAllDay,
);
events.add(event);
}
return SfCalendar(
firstDayOfWeek: 1,
dataSource: EventDataSource(events),
view: CalendarView.month,
onLongPress: (details) {
final eventViewModel = Provider.of<EventViewModel>(context, listen: false);
eventViewModel.setDate(details.date!);
showModalBottomSheet(
context: context,
builder: (context) => const DailyWidget(),
);
},
);
}
if(!snapshot.hasData) {
return const Loader();
}
if(snapshot.hasError) {
return Utils.showErrorMessage(snapshot.hasError.toString());
}
return Container();
},
);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.