flutter SetState正在工作,但颜色未更改

5jvtdoz2  于 2023-01-31  发布在  Flutter
关注(0)|答案(1)|浏览(171)

我正在使用table_calendar制作日历,我想更改选定的日期。
我使用了setState,它可以工作,但不会更改选定的日期小部件。
我不知道为什么会这样。
我的代码:

import 'dart:collection';

import 'package:flutter/material.dart';
import 'package:table_calendar/table_calendar.dart';
import 'dart:developer' as developer;
import '../widgets/table_calendar_util.dart';

class LessonBody extends StatefulWidget {
  const LessonBody({super.key});

  @override
  State<LessonBody> createState() => _LessonBodyState();
}

class _LessonBodyState extends State<LessonBody> {
  // Using a `LinkedHashSet` is recommended due to equality comparison override
  final Set<DateTime> _selectedDays = LinkedHashSet<DateTime>(
    equals: isSameDay,
    hashCode: getHashCode,
  );

  CalendarFormat _calendarFormat = CalendarFormat.week;
  DateTime _focusedDay = DateTime.now();
  DateTime _selectedDay = DateTime.now();
  Map<DateTime, List<Event>>? _noteMapByDay;

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Column(
        children: [
          Stack(
            children: [
              TableCalendar<Event>(
                calendarStyle: const CalendarStyle(
                  todayDecoration: BoxDecoration(
                    color: Colors.green,
                    shape: BoxShape.circle,
                  ),
                  markerDecoration: BoxDecoration(
                    color: Colors.red,
                    shape: BoxShape.rectangle,
                  ),
                ),
                firstDay: kFirstDay,
                lastDay: kLastDay,
                focusedDay: _focusedDay,
                calendarFormat: _calendarFormat,
                eventLoader: (day) {
                  if (_noteMapByDay != null) {
                    return _noteMapByDay![day] ?? [];
                  } else {
                    return [];
                  }
                },
                startingDayOfWeek: StartingDayOfWeek.monday,
                selectedDayPredicate: (day) {
                  // Use values from Set to mark multiple days as selected
                  return _selectedDays.contains(day);
                },
                onDaySelected: (selectedDay, focusedDay) {
                  setState(() {
                    _selectedDay = selectedDay;
                    _focusedDay = focusedDay;
                    developer.log('focusedDay : $_focusedDay');
                    developer.log('selectedDay : $_selectedDay');
                  });
                  developer.log('select');
                },
                onFormatChanged: (format) {
                  if (_calendarFormat != format) {
                    setState(() {
                      _calendarFormat = format;
                      developer.log('onFormatChanged : ${format.name}');
                    });
                  }
                },
                onPageChanged: (focusedDay) {
                  _focusedDay = focusedDay;
                },
              ),

              // 주, 2주, 월 단위로 보여주기
              Positioned(
                right: 60,
                top: 9,
                child: Align(
                  alignment: Alignment.topRight,
                  child: TextButton.icon(
                      onPressed: () {
                        setState(() {
                          switch (_calendarFormat) {
                            case CalendarFormat.week:
                              _calendarFormat = CalendarFormat.twoWeeks;
                              break;
                            case CalendarFormat.twoWeeks:
                              _calendarFormat = CalendarFormat.month;
                              break;
                            case CalendarFormat.month:
                              _calendarFormat = CalendarFormat.week;
                              break;
                            default:
                          }
                        });
                      },
                      icon: const Icon(
                        Icons.calendar_month_rounded,
                        color: Colors.green,
                      ),
                      label: _calendarFormat == CalendarFormat.week
                          ? const Text(
                              '주',
                              style: TextStyle(color: Colors.green),
                            )
                          : _calendarFormat == CalendarFormat.twoWeeks
                              ? const Text(
                                  '2주',
                                  style: TextStyle(color: Colors.green),
                                )
                              : const Text(
                                  '월',
                                  style: TextStyle(color: Colors.green),
                                )),
                ),
              ),
              
            ],
          ),
          const SizedBox(
            height: 15,
          ),
        ],
      ),
    );
  }
}

感谢您阅读本文。

lzfw57am

lzfw57am1#

看起来问题出在TableCalendar小部件中的selectedDayPredicate函数上。您正在使用LinkedHashSet来跟踪选定的日期,但当用户选择新的日期时,您没有更新它。
您可以尝试在调用onDaySelected回调时将所选日期添加到集合中:

onDaySelected: (selectedDay, focusedDay) {
  setState(() {
    _selectedDays.add(selectedDay);
    _selectedDay = selectedDay;
    _focusedDay = focusedDay;
    developer.log('focusedDay : $_focusedDay');
    developer.log('selectedDay : $_selectedDay');
  });
  developer.log('select');
}

相关问题