简体   繁体   English

表日历 Flutter

[英]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.

相关问题 显示 TableCalendar 中的事件数 Flutter - Display number of events in TableCalendar Flutter 如何防止用户在 TableCalendar 中颤抖选择假期? - how to prevent user to chose holiday in TableCalendar with flutter? Flutter TableCalendar:如何更改所选日期模式 - Flutter TableCalendar: how to change day selected pattern 将 cursor 更改为 TableCalendar 中的指针 for flutter web - Change cursor to Pointer in TableCalendar for flutter web 如何在 flutter 表日历中禁用滑动月份 - How to disable swipe month in flutter tablecalendar 在 Dart Flutter 项目中将 TableCalendar 中的 FirstDay 设置为当月的第一天 - Setting the FirstDay in TableCalendar to the First day of the current month in Dart Flutter Project Flutter/Dart 使用 Calendar API / TableCalendar package 的 enabledDayPredicate 禁用多个工作日 - Flutter/Dart Disable Multiple Week Days using enabledDayPredicate of Calendar API / TableCalendar package onFormatChanged() 不适用于 TableCalendar - onFormatChanged() not working with TableCalendar 如何将 locale 属性设置为 TableCalendar 小部件 - How to set the locale property to TableCalendar widget 在 TableCalendar Package 上使用 _onVisibleDaysChanged 时如何获取当前年份和月份 - How to get current year and month when using _onVisibleDaysChanged on TableCalendar Package
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM