diff --git a/lib/src/table_calendar.dart b/lib/src/table_calendar.dart index bcd52656..fd910a7f 100644 --- a/lib/src/table_calendar.dart +++ b/lib/src/table_calendar.dart @@ -3,6 +3,7 @@ import 'dart:math'; +import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:intl/intl.dart'; import 'package:simple_gesture_detector/simple_gesture_detector.dart'; @@ -106,6 +107,9 @@ class TableCalendar extends StatefulWidget { /// Whether to display week numbers on calendar. final bool weekNumbersVisible; + /// Wether to display only weekdays + final bool onlyWeekdays; + /// Used for setting the height of `TableCalendar`'s rows. final double rowHeight; @@ -228,6 +232,7 @@ class TableCalendar extends StatefulWidget { this.sixWeekMonthsEnforced = false, this.shouldFillViewport = false, this.weekNumbersVisible = false, + this.onlyWeekdays = false, this.rowHeight = 52.0, this.daysOfWeekHeight = 16.0, this.formatAnimationDuration = const Duration(milliseconds: 200), @@ -505,6 +510,8 @@ class _TableCalendarState extends State> { simpleSwipeConfig: widget.simpleSwipeConfig, sixWeekMonthsEnforced: widget.sixWeekMonthsEnforced, onVerticalSwipe: _swipeCalendarFormat, + onlyWeekdays: widget.onlyWeekdays, + weekendDays: widget.weekendDays, onPageChanged: (focusedDay) { _focusedDay.value = focusedDay; widget.onPageChanged?.call(focusedDay); @@ -519,9 +526,18 @@ class _TableCalendarState extends State> { cell = Padding( padding: const EdgeInsets.symmetric(horizontal: 4), child: Center( - child: Text( - weekNumber.toString(), - style: widget.calendarStyle.weekNumberTextStyle, + child: Column( + children: [ + Icon( + Icons.beach_access, + color: Colors.blue, + size: 36.0, + ), + Text( + weekNumber.toString(), + style: widget.calendarStyle.weekNumberTextStyle, + ), + ], ), ), ); diff --git a/lib/src/table_calendar_base.dart b/lib/src/table_calendar_base.dart index 659a43a7..ea0444bb 100644 --- a/lib/src/table_calendar_base.dart +++ b/lib/src/table_calendar_base.dart @@ -36,6 +36,8 @@ class TableCalendarBase extends StatefulWidget { final SwipeCallback? onVerticalSwipe; final void Function(DateTime focusedDay)? onPageChanged; final void Function(PageController pageController)? onCalendarCreated; + final bool? onlyWeekdays; + final List weekendDays; TableCalendarBase({ Key? key, @@ -74,6 +76,8 @@ class TableCalendarBase extends StatefulWidget { this.onVerticalSwipe, this.onPageChanged, this.onCalendarCreated, + this.onlyWeekdays = false, + this.weekendDays = const [DateTime.saturday, DateTime.sunday], }) : assert(!dowVisible || (dowHeight != null && dowBuilder != null)), assert(isSameDay(focusedDay, firstDay) || focusedDay.isAfter(firstDay)), assert(isSameDay(focusedDay, lastDay) || focusedDay.isBefore(lastDay)), @@ -251,6 +255,8 @@ class _TableCalendarBaseState extends State { }, dowBuilder: widget.dowBuilder, dayBuilder: widget.dayBuilder, + onlyWeekdays: widget.onlyWeekdays, + weekendDays: widget.weekendDays, ), ), ); diff --git a/lib/src/widgets/calendar_core.dart b/lib/src/widgets/calendar_core.dart index d196296f..2f64fb5c 100644 --- a/lib/src/widgets/calendar_core.dart +++ b/lib/src/widgets/calendar_core.dart @@ -32,7 +32,8 @@ class CalendarCore extends StatelessWidget { final PageController? pageController; final ScrollPhysics? scrollPhysics; final _OnCalendarPageChanged onPageChanged; - + final bool? onlyWeekdays; + final List weekendDays; const CalendarCore({ Key? key, this.dowBuilder, @@ -57,6 +58,8 @@ class CalendarCore extends StatelessWidget { this.tableBorder, this.tablePadding, this.scrollPhysics, + this.onlyWeekdays = false, + this.weekendDays = const [DateTime.saturday, DateTime.sunday], }) : assert(!dowVisible || (dowHeight != null && dowBuilder != null)), super(key: key); @@ -69,7 +72,9 @@ class CalendarCore extends StatelessWidget { itemBuilder: (context, index) { final baseDay = _getBaseDay(calendarFormat, index); final visibleRange = _getVisibleRange(calendarFormat, baseDay); - final visibleDays = _daysInRange(visibleRange.start, visibleRange.end); + final visibleDays = onlyWeekdays == false + ? _daysInRange(visibleRange.start, visibleRange.end) + : _weekdaysInRange(visibleRange.start, visibleRange.end); final actualDowHeight = dowVisible ? dowHeight! : 0.0; final constrainedRowHeight = constraints.hasBoundedHeight @@ -84,6 +89,7 @@ class CalendarCore extends StatelessWidget { rowDecoration: rowDecoration, tableBorder: tableBorder, tablePadding: tablePadding, + daysInWeek: onlyWeekdays == false ? 7 : 5, dowBuilder: (context, day) { return SizedBox( height: dowHeight, @@ -267,6 +273,17 @@ class CalendarCore extends StatelessWidget { ); } + List _weekdaysInRange(DateTime first, DateTime last) { + int dayCount = (last.difference(first).inDays + 1); + List weekdays = List.generate( + dayCount, + (index) => DateTime.utc(first.year, first.month, first.day + index), + ); + + weekdays.removeWhere((element) => weekendDays.contains(element.weekday)); + return weekdays; + } + DateTime _firstDayOfWeek(DateTime week) { final daysBefore = _getDaysBefore(week); return week.subtract(Duration(days: daysBefore)); diff --git a/lib/src/widgets/calendar_header.dart b/lib/src/widgets/calendar_header.dart index cce74329..c73bed05 100644 --- a/lib/src/widgets/calendar_header.dart +++ b/lib/src/widgets/calendar_header.dart @@ -3,6 +3,7 @@ import 'package:flutter/widgets.dart'; import 'package:intl/intl.dart'; +import 'package:flutter/material.dart'; import '../customization/header_style.dart'; import '../shared/utils.dart' show CalendarFormat, DayBuilder; @@ -46,51 +47,66 @@ class CalendarHeader extends StatelessWidget { decoration: headerStyle.decoration, margin: headerStyle.headerMargin, padding: headerStyle.headerPadding, - child: Row( - mainAxisSize: MainAxisSize.max, + child: Column( children: [ - if (headerStyle.leftChevronVisible) - CustomIconButton( - icon: headerStyle.leftChevronIcon, - onTap: onLeftChevronTap, - margin: headerStyle.leftChevronMargin, - padding: headerStyle.leftChevronPadding, - ), - Expanded( - child: headerTitleBuilder?.call(context, focusedMonth) ?? - GestureDetector( - onTap: onHeaderTap, - onLongPress: onHeaderLongPress, - child: Text( - text, - style: headerStyle.titleTextStyle, - textAlign: headerStyle.titleCentered - ? TextAlign.center - : TextAlign.start, - ), + Row( + mainAxisSize: MainAxisSize.max, + children: [ + if (headerStyle.leftChevronVisible) + CustomIconButton( + icon: headerStyle.leftChevronIcon, + onTap: onLeftChevronTap, + margin: headerStyle.leftChevronMargin, + padding: headerStyle.leftChevronPadding, + ), + Expanded( + child: headerTitleBuilder?.call(context, focusedMonth) ?? + GestureDetector( + onTap: onHeaderTap, + onLongPress: onHeaderLongPress, + child: Text( + text, + style: headerStyle.titleTextStyle, + textAlign: headerStyle.titleCentered + ? TextAlign.center + : TextAlign.start, + ), + ), + ), + // if (headerStyle.formatButtonVisible && + // availableCalendarFormats.length > 1) + // Padding( + // padding: const EdgeInsets.only(left: 8.0), + // child: FormatButton( + // onTap: onFormatButtonTap, + // availableCalendarFormats: availableCalendarFormats, + // calendarFormat: calendarFormat, + // decoration: headerStyle.formatButtonDecoration, + // padding: headerStyle.formatButtonPadding, + // textStyle: headerStyle.formatButtonTextStyle, + // showsNextFormat: headerStyle.formatButtonShowsNext, + // ), + // ), + if (headerStyle.rightChevronVisible) + CustomIconButton( + icon: headerStyle.rightChevronIcon, + onTap: onRightChevronTap, + margin: headerStyle.rightChevronMargin, + padding: headerStyle.rightChevronPadding, ), + ], ), - if (headerStyle.formatButtonVisible && - availableCalendarFormats.length > 1) - Padding( - padding: const EdgeInsets.only(left: 8.0), - child: FormatButton( - onTap: onFormatButtonTap, - availableCalendarFormats: availableCalendarFormats, - calendarFormat: calendarFormat, - decoration: headerStyle.formatButtonDecoration, - padding: headerStyle.formatButtonPadding, - textStyle: headerStyle.formatButtonTextStyle, - showsNextFormat: headerStyle.formatButtonShowsNext, + Container( + width: double.infinity, + height: 1.5, + decoration: BoxDecoration( + color: Colors.white, + border: Border.all( + color: Color(0xFFFFEFD1), + width: 1.5, ), ), - if (headerStyle.rightChevronVisible) - CustomIconButton( - icon: headerStyle.rightChevronIcon, - onTap: onRightChevronTap, - margin: headerStyle.rightChevronMargin, - padding: headerStyle.rightChevronPadding, - ), + ), ], ), ); diff --git a/lib/src/widgets/calendar_page.dart b/lib/src/widgets/calendar_page.dart index a13cb62b..3bb2776b 100644 --- a/lib/src/widgets/calendar_page.dart +++ b/lib/src/widgets/calendar_page.dart @@ -15,6 +15,7 @@ class CalendarPage extends StatelessWidget { final bool dowVisible; final bool weekNumberVisible; final double? dowHeight; + final int daysInWeek; const CalendarPage({ Key? key, @@ -29,6 +30,7 @@ class CalendarPage extends StatelessWidget { this.dowVisible = true, this.weekNumberVisible = false, this.dowHeight, + required this.daysInWeek, }) : assert(!dowVisible || (dowHeight != null && dowBuilder != null)), assert(!weekNumberVisible || weekNumberBuilder != null), super(key: key); @@ -56,12 +58,12 @@ class CalendarPage extends StatelessWidget { } Widget _buildWeekNumbers(BuildContext context) { - final rowAmount = visibleDays.length ~/ 7; + final rowAmount = visibleDays.length ~/ daysInWeek; return Column( children: [ if (dowVisible) SizedBox(height: dowHeight ?? 0), - ...List.generate(rowAmount, (index) => index * 7) + ...List.generate(rowAmount, (index) => index * daysInWeek) .map((index) => Expanded( child: weekNumberBuilder!(context, visibleDays[index]), )) @@ -74,20 +76,20 @@ class CalendarPage extends StatelessWidget { return TableRow( decoration: dowDecoration, children: List.generate( - 7, + daysInWeek, (index) => dowBuilder!(context, visibleDays[index]), ).toList(), ); } List _buildCalendarDays(BuildContext context) { - final rowAmount = visibleDays.length ~/ 7; + final rowAmount = visibleDays.length ~/ daysInWeek; - return List.generate(rowAmount, (index) => index * 7) + return List.generate(rowAmount, (index) => index * daysInWeek) .map((index) => TableRow( decoration: rowDecoration, children: List.generate( - 7, + daysInWeek, (id) => dayBuilder(context, visibleDays[index + id]), ), )) diff --git a/lib/src/widgets/cell_content.dart b/lib/src/widgets/cell_content.dart index eb75716c..c0d94edb 100644 --- a/lib/src/widgets/cell_content.dart +++ b/lib/src/widgets/cell_content.dart @@ -115,7 +115,11 @@ class CellContent extends StatelessWidget { padding: padding, decoration: calendarStyle.todayDecoration, alignment: alignment, - child: Text(text, style: calendarStyle.todayTextStyle), + child: Column( + children: [ + Text(text, style: calendarStyle.todayTextStyle), + ], + ), ); } else if (isHoliday) { cell = calendarBuilders.holidayBuilder?.call(context, day, focusedDay) ??