flutter 表日历抖动

ckx4rj1h  于 2023-01-18  发布在  Flutter
关注(0)|答案(1)|浏览(227)

请救救我!
我用flutter创建了一个可用性日历,这个日历只检查可用性日历,没有书,我使用HTTP,iCalendar_Parser和Table_Calendar包。
本页编码

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;
                  });
                }
              })),
            ),
          ],
        ),
      ),
    );
  }
}

这是实用程序页面

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});
}

这显示了错误

误差
抛出了另一个异常:类型"Null"不是类型"String"的子类型
我不知道我错过了什么,请帮助我如何设置事件,没有可用性将阻止与颜色橙色
我想这样显示日历

dced5bon

dced5bon1#

当前,您正尝试将NullMap为string,并通过尝试将event[“DTSTART”]解析为DateTime来使用此Null值,如上面的错误图像所示。

event变量是一个Map值,它由event[“dtstart”]组成,但没有event[“DTSTART”]。这些变量区分大小写。因此,你需要一个fromJson或fromMap方法来将这些json对象Map到Event类型的对象。2希望它能有所帮助。

相关问题