[英]TableCalendar Flutter
Please Help!!请帮忙!!
I create an availability calendar using flutter, this calendar just only checks the availability calendar no book, I use HTTP, iCalendar_Parser, and Table_Calendar packages.我使用 flutter 创建可用性日历,此日历仅检查可用性日历没有书,我使用 HTTP、iCalendar_Parser 和 Table_Calendar 包。
This Page Code本页代码
import '../utils.dart';
import 'package:flutter/material.dart';
import 'dart:core';
import 'package:table_calendar/table_calendar.dart';
import 'package:icalendar_parser/icalendar_parser.dart';
import 'package:http/http.dart' as http;
class TestIcal extends StatefulWidget {
const TestIcal({super.key});
@override
State<TestIcal> createState() => _TestIcalState();
}
class _TestIcalState extends State<TestIcal> {
ICalendar? _iCalendar;
late final ValueNotifier<List<Event>> _selectedEvents;
CalendarFormat _calendarFormat = CalendarFormat.month;
RangeSelectionMode _rangeSelectionMode = RangeSelectionMode.toggledOn;
DateTime _focusedDay = DateTime.now();
DateTime? _selectedDay;
DateTime? _rangeStart;
DateTime? _rangeEnd;
@override
void initState() {
super.initState();
_selectedEvents = ValueNotifier<List<Event>>([]);
_getAssets();
}
Map<DateTime, List<Event>> _convertIcalendarToCalendarFormat() {
if (_iCalendar == null) return {};
Map<DateTime, List<Event>> events = {};
for (var i = 0; i < _iCalendar!.data.length; i++) {
final event = _iCalendar!.data[i];
final start = DateTime.parse(event["DTSTART"]);
final end = DateTime.parse(event["DTEND"]);
final eventName = event["SUMMARY"];
final eventMap = Event(
name: eventName,
start: start,
end: end,
color: Color.fromARGB(255, 255, 165, 0),
);
if (events[start] == null) {
events[start] = [eventMap];
} else {
events[start]?.add(eventMap);
}
}
return events;
}
Future<void> _getAssets() async {
http.Response response = await http.get(
Uri.parse('https://login.smoobu.com/ical/1400834.ics?s=EaTkC2hLcm'),
);
if (response.statusCode != 200) {
print("Error: ${response.statusCode}");
}
final iCalendar = ICalendar.fromString(response.body);
setState(() {
_iCalendar = iCalendar;
});
}
List<Event> _getEventsForDay(DateTime day) {
return _convertIcalendarToCalendarFormat()[day] ?? [];
}
List<Event> _getEventsForRange(DateTime start, DateTime end) {
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);
_rangeEnd = null;
_rangeSelectionMode = RangeSelectionMode.toggledOn;
for (Event event in _getEventsForDay(selectedDay)) {
event.color = Color.fromARGB(255, 255, 165, 0);
}
});
}
}
void _onRangeSelected(DateTime? start, DateTime? end, DateTime focusedDay) {
setState(() {
_selectedDay = null;
_focusedDay = focusedDay;
_rangeStart = start;
_rangeEnd = end;
_rangeSelectionMode = RangeSelectionMode.toggledOn;
});
if (start != null && end != null) {
_selectedEvents.value = _getEventsForRange(start, end);
for (Event event in _getEventsForRange(start, end)) {
event.color = Color.fromARGB(255, 255, 165, 0);
}
} else if (start != null) {
_selectedEvents.value = _getEventsForDay(start);
for (Event event in _getEventsForDay(start)) {
event.color = Color.fromARGB(255, 255, 165, 0);
}
} else if (end != null) {
_selectedEvents.value = _getEventsForDay(end);
for (Event event in _getEventsForDay(end)) {
event.color = Color.fromARGB(255, 255, 165, 0);
}
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Test Ical'),
),
body: SingleChildScrollView(
padding: const EdgeInsets.all(16),
child: Column(
children: [
TableCalendar<Event>(
focusedDay: _focusedDay,
firstDay: DateTime.now(),
lastDay: DateTime(2025, 12, 31),
calendarFormat: _calendarFormat,
rangeSelectionMode: _rangeSelectionMode,
eventLoader: _getEventsForDay,
selectedDayPredicate: ((day) => isSameDay(_selectedDay, day)),
rangeStartDay: _rangeStart,
rangeEndDay: _rangeEnd,
onDaySelected: _onDaySelected,
onRangeSelected: _onRangeSelected,
onFormatChanged: (((format) {
if (_calendarFormat != format) {
setState(() {
_calendarFormat = format;
});
}
})),
),
],
),
),
);
}
}
And this the utils page这是实用程序页面
import 'dart:ui';
List<DateTime> daysInRange(DateTime start, DateTime end) {
final days = <DateTime>[];
for (var day = start; day.isBefore(end); day = day.add(Duration(days: 1))) {
days.add(day);
}
return days;
}
class Event {
final String name;
final DateTime? start;
final DateTime? end;
Color color;
Event({required this.name, this.start, this.end, required this.color});
}
and this is showing and the error这是显示和错误
error错误
Another exception was thrown: type 'Null' is not a subtype of type 'String'
抛出另一个异常:类型“Null”不是类型“String”的子类型
I don't know where I miss it, please help me how to set event with no availability will block with color orange我不知道我在哪里错过了它,请帮助我如何设置没有可用性的事件将阻止颜色为橙色
I want to display the calendar like this我想这样显示日历
Currently you are trying to map Null into string and you are using this null value by trying to parse event["DTSTART"] into a DateTime as shown in the error image above.当前,您正在尝试将 map Null 转换为字符串,并且您通过尝试将 event["DTSTART"] 解析为 DateTime 来使用此 null 值,如上图所示的错误图像。
The event variable is a Map value which consists event["dtstart"] but does not have event["DTSTART"].
事件变量是一个 Map 值,它包含事件 ["dtstart"] 但没有事件 ["DTSTART"]。 These are case sensitive.
这些是区分大小写的。 So, you need a fromJson or fromMap methods to map these json objects into object of type Event.
所以,你需要一个fromJson或者fromMap方法把map这些json对象转化为object类型的Event。 Hope it helps.
希望能帮助到你。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.