table_calendar
table_calendar copied to clipboard
todayBuilder not working
The bug
So basically todayBuilder under CalendarBuilders is not working. Though it was made with the intention of customizing the today's date, but nothing is happening. But rather a kind of blue background appears after focusing to another date on today's date.
Even log("TODAY BUILDER: $date"); isn't triggered.
To reproduce
todayBuilder code only
todayBuilder: (context, date, _) {
log("TODAY BUILDER: $date");
return Container(
margin: const EdgeInsets.all(4),
alignment: Alignment.center,
decoration: BoxDecoration(
color: Colors.green,
shape: BoxShape.circle,
),
child: Text(
date.day.toString(),
style: const TextStyle(color: Colors.white),
),
);
},
Full Code
import 'dart:collection';
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:mood_tracker/models/first_day_of_week_model.dart';
import 'package:mood_tracker/utils/constant.dart';
import 'package:mood_tracker/view_models/mood_view_model.dart';
import 'package:mood_tracker/views/core/single_item_card.dart';
import 'package:provider/provider.dart';
import 'package:table_calendar/table_calendar.dart';
import '../../../utils/date_helper_utils.dart';
import '../utils.dart' as utils;
class Calendar extends StatefulWidget {
final LinkedHashMap<DateTime, List<MoodViewModel>> moods;
const Calendar({super.key, required this.moods});
@override
State<Calendar> createState() => _CalendarState();
}
class _CalendarState extends State<Calendar> {
// for knowing if the selected days have any event to display
late final ValueNotifier<List<MoodViewModel>> _selectedEvents;
DateTime _focusedDay = DateTime.now();
DateTime? _selectedDay;
// for making viewing spaces more by hiding calendar dates
CalendarFormat currentCalendarFormat = CalendarFormat.month;
var kEvents = LinkedHashMap<DateTime, List<MoodViewModel>>(
equals: (DateTime? a, DateTime? b) {
if (a == null || b == null) {
return false;
}
return a.year == b.year && a.month == b.month && a.day == b.day;
},
hashCode: (DateTime key) =>
key.day * 1000000 + key.month * 10000 + key.year,
);
List<MoodViewModel> _getEventsForDay(DateTime date) {
// if selected days has no event then return empty
return kEvents[date] ?? [];
}
void _onDaySelected(DateTime selectedDay, DateTime focusedDay) {
if (!isSameDay(_selectedDay, selectedDay)) {
setState(() {
_selectedDay = selectedDay;
_focusedDay = focusedDay;
});
_selectedEvents.value = _getEventsForDay(selectedDay);
}
}
@override
void initState() {
super.initState();
kEvents.addAll(widget.moods);
_selectedDay = _focusedDay;
_selectedEvents = ValueNotifier(_getEventsForDay(_selectedDay!));
}
@override
void dispose() {
_selectedEvents.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Column(
children: [
FutureBuilder(
future:
Provider.of<FirstDayOfWeekModel>(context).getFirstDayOfWeek(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(child: CircularProgressIndicator());
} else if (snapshot.hasError) {
return const Center(child: Text("Something went wrong"));
}
return TableCalendar<MoodViewModel>(
calendarFormat: currentCalendarFormat,
firstDay: widget.moods.keys.first,
rangeEndDay: utils.kLastDay,
headerStyle: HeaderStyle(
formatButtonVisible: true,
titleCentered: true,
formatButtonDecoration: BoxDecoration(
color: Constant().colors.blue,
border: Border.all(color: Constant().colors.primary),
borderRadius: const BorderRadius.all(Radius.circular(10)),
),
),
onFormatChanged: (format) {
setState(() => currentCalendarFormat = format);
},
availableCalendarFormats: const {
CalendarFormat.month: 'Month',
CalendarFormat.week: 'Week',
},
calendarBuilders: CalendarBuilders(
// for displaying today
todayBuilder: (context, date, _) {
log("TODAY BUILDER: $date");
return Container(
margin: const EdgeInsets.all(4),
alignment: Alignment.center,
decoration: BoxDecoration(
color: Colors.green,
shape: BoxShape.circle,
),
child: Text(
date.day.toString(),
style: const TextStyle(color: Colors.white),
),
);
},
// marker for how many events in that day
markerBuilder: (context, date, events) {
if (events.isEmpty) {
return null;
}
return Positioned(
bottom: 1,
right: 1,
child: Container(
padding: const EdgeInsets.all(2),
decoration: BoxDecoration(
color: Colors.green,
borderRadius: BorderRadius.circular(10),
),
child: Text(
events.length.toString(),
style: const TextStyle(color: Colors.white),
),
),
);
},
// for displaying selected day
selectedBuilder: (context, date, _) {
log("SELECTED BUILDER: $date");
return Container(
margin: const EdgeInsets.all(4),
alignment: Alignment.center,
decoration: BoxDecoration(
color: Constant().colors.yellow,
border: Border.all(color: Constant().colors.primary),
shape: BoxShape.circle,
),
child: Text(
date.day.toString(),
style: const TextStyle(color: Colors.white),
),
);
},
),
lastDay: utils.kLastDay,
focusedDay: _focusedDay,
selectedDayPredicate: (day) => isSameDay(_selectedDay, day),
eventLoader: _getEventsForDay,
startingDayOfWeek: DateHelperUtils()
.firstDayOfWeekString(firstDayOfWeek: snapshot.data!),
calendarStyle: const CalendarStyle(
markerSize: 10,
markersMaxCount: 24,
outsideDaysVisible: false,
canMarkersOverflow: true,
),
onDaySelected: _onDaySelected,
);
}),
Expanded(
child: ValueListenableBuilder<List<MoodViewModel>>(
valueListenable: _selectedEvents,
builder: (context, moodViewModels, _) {
return ListView.builder(
itemCount: moodViewModels.length,
itemBuilder: (context, index) {
return SingleItemCard(
date: moodViewModels[index].date,
dateLabel: DateHelperUtils()
.getDateLabel(moodViewModels[index].date),
rating: moodViewModels[index].rating,
timeStamp: moodViewModels[index].timestamp,
feedback: moodViewModels[index].feedback,
reason: moodViewModels[index].reason,
showEditDeleteButton: false,
dbImagesPath: moodViewModels[index].imagesURL,
showImageDeleteBtn: false,
);
},
);
},
),
),
],
);
}
}
Expected behavior I am expecting todayBuilder to be able to customize the today's date.
Screenshots
Output of flutter doctor
Output
[√] Flutter (Channel stable, 3.7.12, on Microsoft Windows [Version 10.0.22621.1848], locale en-US) • Flutter version 3.7.12 on channel stable at C:\flutter • Upstream repository https://github.com/flutter/flutter.git • Framework revision 4d9e56e694 (9 weeks ago), 2023-04-17 21:47:46 -0400 • Engine revision 1a65d409c7 • Dart version 2.19.6 • DevTools version 2.20.1[√] Windows Version (Installed version of Windows is version 10 or higher)
[√] Android toolchain - develop for Android devices (Android SDK version 33.0.0) • Android SDK at C:\Users\Sulabh Shrestha\AppData\Local\Android\sdk • Platform android-33, build-tools 33.0.0 • Java binary at: C:\Program Files\Android\Android Studio\jbr\bin\java • Java version OpenJDK Runtime Environment (build 17.0.6+0-b2043.56-9586694) • All Android licenses accepted.
[√] Chrome - develop for the web • Chrome at C:\Program Files\Google\Chrome\Application\chrome.exe
[X] Visual Studio - develop for Windows X Visual Studio not installed; this is necessary for Windows development. Download at https://visualstudio.microsoft.com/downloads/. Please install the "Desktop development with C++" workload, including all of its default components
[√] Android Studio (version 2022.2) • Android Studio at C:\Program Files\Android\Android Studio • Flutter plugin can be installed from: https://plugins.jetbrains.com/plugin/9212-flutter • Dart plugin can be installed from: https://plugins.jetbrains.com/plugin/6351-dart • Java version OpenJDK Runtime Environment (build 17.0.6+0-b2043.56-9586694)
[√] VS Code (version 1.79.2) • VS Code at C:\Users\Sulabh Shrestha\AppData\Local\Programs\Microsoft VS Code • Flutter extension version 3.66.0
[√] Connected device (4 available) • Android SDK built for x86 (mobile) • emulator-5554 • android-x86 • Android 10 (API 29) (emulator) • Windows (desktop) • windows • windows-x64 • Microsoft Windows [Version 10.0.22621.1848] • Chrome (web) • chrome • web-javascript • Google Chrome 114.0.5735.134 • Edge (web) • edge • web-javascript • Microsoft Edge 113.0.1774.50
[√] HTTP Host Availability • All required HTTP hosts are available
Try adding just the todayBuilder code to one of the examples and see if behavior persists.