我正在使用日历轮播小部件,并且正在尝试从Cloud Firestore添加事件。 我成功地从firebase获取了日期,问题是只有在单击任何日期后才能看到该日期,因此,当用户第一次查找日历时,服务器端没有有关事件的信息。 如果我返回到父级并返回日历,屏幕也会刷新。 如何刷新日历上的数据?我在网上浏览时,仅发现使用ListViews的示例。
仅当我单击按钮时,才会显示Firebase数据。 (或者返回父级并返回时),如gif所示。
import 'package:flutter/material.dart';
import 'package:father_home_flutter/model/constants.dart';
import 'package:flutter_calendar_carousel/classes/event.dart';
import 'package:flutter_calendar_carousel/classes/event_list.dart';
import 'package:flutter_calendar_carousel/flutter_calendar_carousel.dart'
show CalendarCarousel;
import 'package:cloud_firestore/cloud_firestore.dart';
class ScreenCalendar extends StatefulWidget {
@override
_ScreenCalendarState createState() => new _ScreenCalendarState();
}
class _ScreenCalendarState extends State<ScreenCalendar> {
static String noEventText = "Событий нет";
String tabBarTitle = "Calendar";
String calendarText = noEventText;
DateTime _currentDate = DateTime.now();
Color _colorButtonColor = Colors.indigo;
Color _colorTextButtonColor = Colors.black;
Color _colorTextTodayButton = Colors.white;
static const String _calendarRussian = "calendarRussian";
static const String _eventTitle = "eventTitle";
static const String _eventDay = "eventDay";
static const String _eventMonth = "eventMonth";
static const String _eventYear = "eventYear";
void getCalendarEventList() {
Firestore.instance.collection(_calendarRussian).snapshots().listen((data) =>
data.documents.forEach((doc) => _markedDateMap.add(
new DateTime(int.parse(doc[_eventYear]),
int.parse(doc[_eventMonth]), int.parse(doc[_eventDay])),
new Event(
date: new DateTime(int.parse(doc[_eventYear]),
int.parse(doc[_eventMonth]), int.parse(doc[_eventDay])),
title: doc[_eventTitle],
icon: _eventIcon))
// context.setState(() => refresh(DateTime.now()))}
));
}
@override
void initState() {
getCalendarEventList();
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
tabBarTitle,
style: Constants.myTextStyleAppBar,
),
iconTheme: Constants.myIconThemeDataAppBar,
elevation: Constants.myElevationAppBar,
backgroundColor: Constants.myAppBarColor,
),
body: SingleChildScrollView(
child: Column(children: <Widget>[
Card(
child: CalendarCarousel(
weekendTextStyle: TextStyle(
color: Colors.red,
),
weekFormat: false,
selectedDateTime: _currentDate,
markedDatesMap: _markedDateMap,
selectedDayBorderColor: Colors.transparent,
selectedDayButtonColor: Colors.indigo[300],
todayTextStyle:
TextStyle(color: Colors.black, fontWeight: FontWeight.bold),
selectedDayTextStyle: TextStyle(color: _colorTextButtonColor),
todayBorderColor: Colors.indigo,
weekdayTextStyle: TextStyle(color: Colors.black),
height: 420.0,
daysHaveCircularBorder: true,
todayButtonColor: Colors.transparent,
locale: 'RUS',
onDayPressed: (DateTime date, List<Event> events) {
this.setState(() => refresh(date));
},
)),
Card(
child: Container(
child: Padding(
padding: EdgeInsets.fromLTRB(16.0, 16.0, 16.0, 16.0),
child: Center(
child: Text(
calendarText,
style: Constants.textStyleCommonText,
)))))
])));
}
void refresh(DateTime date) {
_currentDate = date;
print('selected date ' +
date.day.toString() +
date.month.toString() +
date.year.toString() +
' ' +
date.toString());
if (_markedDateMap
.getEvents(new DateTime(date.year, date.month, date.day))
.isNotEmpty) {
calendarText = _markedDateMap
.getEvents(new DateTime(date.year, date.month, date.day))[0]
.title;
} else {
calendarText = noEventText;
}
if (date == _currentDate) {
_colorButtonColor = Colors.indigo;
_colorTextButtonColor = Colors.white;
_colorTextTodayButton = Colors.white;
} else {
_colorTextButtonColor = Colors.indigo;
_colorTextTodayButton = Colors.black;
}
}
}
EventList<Event> _markedDateMap = new EventList<Event>(events: {
new DateTime(2019, 1, 24): [
new Event(
date: new DateTime(2019, 1, 24),
title: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, '
'sed eiusmod tempor incidunt ut labore et dolore magna aliqua.'
' \n\nUt enim ad minim veniam,'
' quis nostrud exercitation ullamco laboris nisi ut aliquid ex ea commodi consequat.'
' \n\nQuis aute iure reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. '
'Excepteur sint obcaecat cupiditat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
icon: _eventIcon,
)
]
});
Widget _eventIcon = new Container(
decoration: new BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(1000)),
border: Border.all(color: Colors.blue, width: 2.0)),
child: new Icon(
Icons.person,
color: Colors.amber,
),
);
答案 0 :(得分:1)
好吧,我找到了一种使用async和await来解决它的方法,这是我更改的代码的一部分。
Future<void> getCalendarEventList() async {
await Firestore.instance.collection(_calendarRussian).snapshots().listen(
(data) => data.documents.forEach((doc) => _markedDateMap.add(
new DateTime(int.parse(doc[_eventYear]),
int.parse(doc[_eventMonth]), int.parse(doc[_eventDay])),
new Event(
date: new DateTime(int.parse(doc[_eventYear]),
int.parse(doc[_eventMonth]), int.parse(doc[_eventDay])),
title: doc[_eventTitle],
icon: _eventIcon))));
setState(() {});
}
为避免重复日历事件,我决定清理marketDataMap:
@override
void dispose(){
_markedDateMap.clear();
super.dispose();
}