Home > other >  SetState is working but the color doesn't change
SetState is working but the color doesn't change

Time:01-29

I'm making a calendar using table_calendar and I want to change the selected day.

I used setState and it works, but doesn't change the selected day widget.

I'm not sure why it's happened.

My code:

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

Thank you for reading this.

CodePudding user response:

It looks like the problem is with the selectedDayPredicate function in the TableCalendar widget. You are using a LinkedHashSet to keep track of selected days, but you are not updating it when the user selects a new day.

You can try adding the selected day to the set when the onDaySelected callback is called:

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

  • Related