使用 Table Calendar Flutter 添加监听器
Add listener with Table Calendar Flutter
嗨,我是 Flutter 的新手(尤其是编码方面的新手),我正在尝试使用 table_calendar 制作日历。我正在寻找一种方法来设置事件的开始和结束日期(保存在 Firebase 中)。小部件中内置的 OnDaySelected 函数似乎对此不起作用,但我认为解决方案是向 _controller.selectedDay 添加一个侦听器,以便每次单击日期时我都可以调用特定函数。
我试过 Value Notifier,但它在 null 时被调用,我不明白为什么。我可以使用 _controller.selectedDay 将日期传递到 AddSchedule 页面,所以我不确定为什么实际日历上的值无法显示。我是不是错误地实施了 ValueNotifier 还是有其他方法可以做到这一点?
class SchedulePage extends StatefulWidget {
@override
_SchedulePageState createState() => _SchedulePageState();
}
class _SchedulePageState extends State<SchedulePage> {
CalendarController _controller;
List routes = [];
List locations = [];
List distinctLocations = [];
List filter = [];
List lastFilter = [];
List selectedEvents = [];
var daySelect;
@override
void initState() {
super.initState();
getRoutes();
_controller = CalendarController();
daySelect = ValueNotifier<DateTime>(_controller.selectedDay);
daySelect.value.notifyListeners();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
getRoutes() async {
final data = await FirebaseFirestore.instance
.collection("Routes")
.orderBy("driver")
.get();
List routeList = List();
for (int i = 0; i < data.docs.length; i++) {
routeList.add(data.docs[i]);
}
routes = routeList;
filter = routes
.where((element) => element['startDate'].toDate().isBefore(_controller.selectedDay)
&& element['endDate'].toDate().isAfter(_controller.selectedDay)).toList();
locations = filter.map((element) => element["locationName"].toString()).toList();
distinctLocations = locations.toSet().toList();
setState(() {});
}
getFilter(DateTime day) {
filter = routes
.where((element) => element['startDate'].toDate().isBefore(day)
&& element['endDate'].toDate().isAfter(day)).toList();
locations = filter.map((element) => element["locationName"].toString()).toList();
distinctLocations = locations.toSet().toList();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey[900],
appBar: AppBar(...),
body: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
height: 210,
decoration: BoxDecoration(color: Colors.grey[900], boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.8),
blurRadius: 10.0,
offset: Offset(0, 10),
),
]),
child: TableCalendar(
calendarController: _controller,
initialCalendarFormat: CalendarFormat.twoWeeks,
calendarStyle: CalendarStyle(
todayColor: Colors.red.withOpacity(0.7),
selectedColor: Color(0xFFF00F12),
weekendStyle: TextStyle(
color: Colors.red, fontWeight: FontWeight.w600),
markersColor: Colors.white,
markersMaxAmount: 1,
weekdayStyle: TextStyle(
color: Colors.white, fontWeight: FontWeight.w600)),
daysOfWeekStyle: DaysOfWeekStyle(
weekdayStyle: TextStyle(
color: Colors.white.withOpacity(0.5),
fontWeight: FontWeight.w600),
),
headerStyle: HeaderStyle(
formatButtonVisible: false,
centerHeaderTitle: true,
titleTextStyle: TextStyle(
color: Colors.red,
fontSize: 19.0,
),
leftChevronIcon:
Icon(Icons.chevron_left, color: Colors.white),
rightChevronIcon: Icon(
Icons.chevron_right,
color: Colors.white,
)),
),
),
SingleChildScrollView(
child: Container(
height: 800,
color: Colors.black38,
child: ValueListenableBuilder(
valueListenable: daySelect,
builder: (context, n, c){
return FutureBuilder(
future: getFilter(daySelect.value),
builder: (context, w) {
if(!w.hasData) {
return _buildSchedule();
} else {
return Center(
child: CircularProgressIndicator(
backgroundColor: Colors.white,
));
}
});
},
),
),
),
],
),
),
floatingActionButton: Container(
height: 45,
width: 45,
child: FittedBox(
child: FloatingActionButton(
backgroundColor: Colors.white,
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(builder: (_) {
return addSchedule(_controller.selectedDay);
}));
},
child: Text(...),
),
),
),
);
}
你可以使用onDaySelected
和setState来改变变量内容
onDaySelected: (date, events, _){
setState(() {
_thisDay = date;
});
},
嗨,我是 Flutter 的新手(尤其是编码方面的新手),我正在尝试使用 table_calendar 制作日历。我正在寻找一种方法来设置事件的开始和结束日期(保存在 Firebase 中)。小部件中内置的 OnDaySelected 函数似乎对此不起作用,但我认为解决方案是向 _controller.selectedDay 添加一个侦听器,以便每次单击日期时我都可以调用特定函数。
我试过 Value Notifier,但它在 null 时被调用,我不明白为什么。我可以使用 _controller.selectedDay 将日期传递到 AddSchedule 页面,所以我不确定为什么实际日历上的值无法显示。我是不是错误地实施了 ValueNotifier 还是有其他方法可以做到这一点?
class SchedulePage extends StatefulWidget {
@override
_SchedulePageState createState() => _SchedulePageState();
}
class _SchedulePageState extends State<SchedulePage> {
CalendarController _controller;
List routes = [];
List locations = [];
List distinctLocations = [];
List filter = [];
List lastFilter = [];
List selectedEvents = [];
var daySelect;
@override
void initState() {
super.initState();
getRoutes();
_controller = CalendarController();
daySelect = ValueNotifier<DateTime>(_controller.selectedDay);
daySelect.value.notifyListeners();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
getRoutes() async {
final data = await FirebaseFirestore.instance
.collection("Routes")
.orderBy("driver")
.get();
List routeList = List();
for (int i = 0; i < data.docs.length; i++) {
routeList.add(data.docs[i]);
}
routes = routeList;
filter = routes
.where((element) => element['startDate'].toDate().isBefore(_controller.selectedDay)
&& element['endDate'].toDate().isAfter(_controller.selectedDay)).toList();
locations = filter.map((element) => element["locationName"].toString()).toList();
distinctLocations = locations.toSet().toList();
setState(() {});
}
getFilter(DateTime day) {
filter = routes
.where((element) => element['startDate'].toDate().isBefore(day)
&& element['endDate'].toDate().isAfter(day)).toList();
locations = filter.map((element) => element["locationName"].toString()).toList();
distinctLocations = locations.toSet().toList();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey[900],
appBar: AppBar(...),
body: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
height: 210,
decoration: BoxDecoration(color: Colors.grey[900], boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.8),
blurRadius: 10.0,
offset: Offset(0, 10),
),
]),
child: TableCalendar(
calendarController: _controller,
initialCalendarFormat: CalendarFormat.twoWeeks,
calendarStyle: CalendarStyle(
todayColor: Colors.red.withOpacity(0.7),
selectedColor: Color(0xFFF00F12),
weekendStyle: TextStyle(
color: Colors.red, fontWeight: FontWeight.w600),
markersColor: Colors.white,
markersMaxAmount: 1,
weekdayStyle: TextStyle(
color: Colors.white, fontWeight: FontWeight.w600)),
daysOfWeekStyle: DaysOfWeekStyle(
weekdayStyle: TextStyle(
color: Colors.white.withOpacity(0.5),
fontWeight: FontWeight.w600),
),
headerStyle: HeaderStyle(
formatButtonVisible: false,
centerHeaderTitle: true,
titleTextStyle: TextStyle(
color: Colors.red,
fontSize: 19.0,
),
leftChevronIcon:
Icon(Icons.chevron_left, color: Colors.white),
rightChevronIcon: Icon(
Icons.chevron_right,
color: Colors.white,
)),
),
),
SingleChildScrollView(
child: Container(
height: 800,
color: Colors.black38,
child: ValueListenableBuilder(
valueListenable: daySelect,
builder: (context, n, c){
return FutureBuilder(
future: getFilter(daySelect.value),
builder: (context, w) {
if(!w.hasData) {
return _buildSchedule();
} else {
return Center(
child: CircularProgressIndicator(
backgroundColor: Colors.white,
));
}
});
},
),
),
),
],
),
),
floatingActionButton: Container(
height: 45,
width: 45,
child: FittedBox(
child: FloatingActionButton(
backgroundColor: Colors.white,
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(builder: (_) {
return addSchedule(_controller.selectedDay);
}));
},
child: Text(...),
),
),
),
);
}
你可以使用onDaySelected
和setState来改变变量内容
onDaySelected: (date, events, _){
setState(() {
_thisDay = date;
});
},