diff --git a/CHANGELOG.md b/CHANGELOG.md index 34481d87..2ba83046 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# [1.4.0](https://github.com/SimformSolutionsPvtLtd/flutter_calendar_view/tree/1.4.0) +- Adds `showWeekends` flag in month view to hide & show weekends view. + Default is `showWeekends = true` shows all weekdays. [#385](https://github.com/SimformSolutionsPvtLtd/flutter_calendar_view/issues/385) +- Fixes issue: Event is shown when days not in current month is hidden `hideDaysNotInMonth = true`. + Events are now hidden for days not in the current month if `hideDaysNotInMonth = true`. +- Fixes `startHour` and `endHour` not updating when rebuilding in week view. [#410](https://github.com/SimformSolutionsPvtLtd/flutter_calendar_view/issues/410) + # [1.3.0 - 12 Nov 2024](https://github.com/SimformSolutionsPvtLtd/flutter_calendar_view/tree/1.3.0) - Fixes full day event position when fullHeaderTitle is empty. @@ -199,4 +206,4 @@ # [0.0.1 - 26 Aug 2021](https://github.com/SimformSolutionsPvtLtd/flutter_calendar_view/tree/0.0.1) -- Initial release \ No newline at end of file +- Initial release diff --git a/README.md b/README.md index 1476d0d2..55732861 100644 --- a/README.md +++ b/README.md @@ -154,6 +154,7 @@ MonthView( headerBuilder: MonthHeader.hidden, // To hide month header showWeekTileBorder: false, // To show or hide header border hideDaysNotInMonth: true, // To hide days or cell that are not in current month + showWeekends: false, // To hide weekends default value is true ); ``` diff --git a/example/lib/widgets/month_view_widget.dart b/example/lib/widgets/month_view_widget.dart index bacec7eb..6bfd75ac 100644 --- a/example/lib/widgets/month_view_widget.dart +++ b/example/lib/widgets/month_view_widget.dart @@ -18,7 +18,9 @@ class MonthViewWidget extends StatelessWidget { return MonthView( key: state, width: width, - hideDaysNotInMonth: false, + showWeekends: false, + useAvailableVerticalSpace: true, + hideDaysNotInMonth: true, onEventTap: (event, date) { Navigator.of(context).push( MaterialPageRoute( diff --git a/lib/src/extensions.dart b/lib/src/extensions.dart index 36077fd0..ef54a08e 100644 --- a/lib/src/extensions.dart +++ b/lib/src/extensions.dart @@ -87,11 +87,37 @@ extension DateTimeExtensions on DateTime { /// All the dates are week based that means it will return array of size 42 /// which will contain 6 weeks that is the maximum number of weeks a month /// can have. - List datesOfMonths({WeekDays startDay = WeekDays.monday}) { + /// + /// It excludes week if `hideDaysNotInMonth` is set true and + /// if all dates in week comes in next month then it will excludes that week. + List datesOfMonths({ + WeekDays startDay = WeekDays.monday, + bool hideDaysNotInMonth = false, + bool showWeekends = false, + }) { final monthDays = []; + // Start is the first weekday for each week in a month for (var i = 1, start = 1; i < 7; i++, start += 7) { - monthDays - .addAll(DateTime(year, month, start).datesOfWeek(start: startDay)); + final datesInWeek = + DateTime(year, month, start).datesOfWeek(start: startDay); + // Check does every date of week belongs to different month + final allDatesNotInCurrentMonth = datesInWeek.every((date) { + if (showWeekends) { + // Include all days + return date.month != month; + } else { + // Exclude weekends (Saturday and Sunday) + return date.weekday == DateTime.saturday || + date.weekday == DateTime.sunday || + date.month != month; + } + }); + + // if entire row contains dates of other month then skip it + if (hideDaysNotInMonth && allDatesNotInCurrentMonth) { + continue; + } + monthDays.addAll(datesInWeek); } return monthDays; } diff --git a/lib/src/month_view/month_view.dart b/lib/src/month_view/month_view.dart index 51690910..15cf14d8 100644 --- a/lib/src/month_view/month_view.dart +++ b/lib/src/month_view/month_view.dart @@ -4,16 +4,8 @@ import 'package:flutter/material.dart'; -import '../calendar_constants.dart'; -import '../calendar_controller_provider.dart'; -import '../calendar_event_data.dart'; -import '../components/components.dart'; +import '../../calendar_view.dart'; import '../constants.dart'; -import '../enumerations.dart'; -import '../event_controller.dart'; -import '../extensions.dart'; -import '../style/header_style.dart'; -import '../typedefs.dart'; class MonthView extends StatefulWidget { /// A function that returns a [Widget] that determines appearance of @@ -64,6 +56,14 @@ class MonthView extends StatefulWidget { /// This method will be called when user double taps on event tile. final TileTapCallback? onEventDoubleTap; + /// Show weekends or not. + /// Default value is true. + /// + /// Similar to [WeekView], + /// If it is false week view will remove weekends from week days + /// and events on weekends will not be shown. + final bool showWeekends; + /// Builds the name of the weeks. /// /// Used default week builder if null. @@ -184,6 +184,7 @@ class MonthView extends StatefulWidget { this.maxMonth, this.controller, this.initialMonth, + this.showWeekends = true, this.borderSize = 1, this.useAvailableVerticalSpace = false, this.cellAspectRatio = 0.55, @@ -352,7 +353,7 @@ class MonthViewState extends State> { width: _width, child: Row( children: List.generate( - 7, + widget.showWeekends ? 7 : 5, (index) => Expanded( child: SizedBox( width: _cellWidth, @@ -365,10 +366,16 @@ class MonthViewState extends State> { ), Expanded( child: LayoutBuilder(builder: (context, constraints) { + final dates = date.datesOfMonths( + startDay: widget.startDay, + hideDaysNotInMonth: widget.hideDaysNotInMonth, + showWeekends: widget.showWeekends, + ); final _cellAspectRatio = widget.useAvailableVerticalSpace ? calculateCellAspectRatio( - constraints.maxHeight, + height: constraints.maxHeight, + daysInMonth: dates.length, ) : widget.cellAspectRatio; @@ -391,6 +398,7 @@ class MonthViewState extends State> { startDay: widget.startDay, physics: widget.pagePhysics, hideDaysNotInMonth: widget.hideDaysNotInMonth, + weekDays: widget.showWeekends ? 7 : 5, ), ); }), @@ -432,8 +440,12 @@ class MonthViewState extends State> { _height = _cellHeight * 6; } - double calculateCellAspectRatio(double height) { - final _cellHeight = height / 6; + double calculateCellAspectRatio({ + required double height, + required int daysInMonth, + }) { + final rows = daysInMonth / 7; + final _cellHeight = height / rows; return _cellWidth / _cellHeight; } @@ -663,6 +675,7 @@ class _MonthPageBuilder extends StatelessWidget { final WeekDays startDay; final ScrollPhysics physics; final bool hideDaysNotInMonth; + final int weekDays; const _MonthPageBuilder({ Key? key, @@ -680,25 +693,32 @@ class _MonthPageBuilder extends StatelessWidget { required this.startDay, required this.physics, required this.hideDaysNotInMonth, + required this.weekDays, }) : super(key: key); @override Widget build(BuildContext context) { - final monthDays = date.datesOfMonths(startDay: startDay); - return Container( + final monthDays = _filteredDays; + + // Highlight tiles which is not in current month + return SizedBox( width: width, height: height, child: GridView.builder( padding: EdgeInsets.zero, physics: physics, gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 7, + crossAxisCount: weekDays, childAspectRatio: cellRatio, ), - itemCount: 42, + itemCount: monthDays.length, shrinkWrap: true, itemBuilder: (context, index) { - final events = controller.getEventsOnDay(monthDays[index]); + // Hide events if `hideDaysNotInMonth` true + final events = + hideDaysNotInMonth & (monthDays[index].month != date.month) + ? >[] + : controller.getEventsOnDay(monthDays[index]); return GestureDetector( onTap: () => onCellTap?.call(events, monthDays[index]), onLongPress: () => onDateLongPress?.call(monthDays[index]), @@ -724,6 +744,32 @@ class _MonthPageBuilder extends StatelessWidget { ), ); } + + /// Returns a list of dates for the month, excluding weekends + /// if the weekDays parameter is set or showWeekends = false. + /// + /// This getter first retrieves all the dates of the month using the + /// `datesOfMonths` method, considering the `startDay` and + /// `hideDaysNotInMonth` parameters. + /// It then filters out the weekend dates (Saturday and Sunday) + /// if the `weekDays` parameter is set to 5, ensuring only + /// weekdays are included in the returned list. + List get _filteredDays { + final monthDays = date.datesOfMonths( + startDay: startDay, + hideDaysNotInMonth: hideDaysNotInMonth, + showWeekends: weekDays == 7, + ); + + return monthDays.where((day) { + final isWeekend = + day.weekday == DateTime.saturday || day.weekday == DateTime.sunday; + if (weekDays == 5 && isWeekend) { + return false; + } + return true; + }).toList(); + } } class MonthHeader { diff --git a/lib/src/week_view/week_view.dart b/lib/src/week_view/week_view.dart index f5fd9cbc..6b0001d0 100644 --- a/lib/src/week_view/week_view.dart +++ b/lib/src/week_view/week_view.dart @@ -468,6 +468,8 @@ class WeekViewState extends State> { } _eventArranger = widget.eventArranger ?? SideEventArranger(); + _startHour = widget.startHour; + _endHour = widget.endHour; // Update heights. _calculateHeights();