Skip to content

Commit 095ede2

Browse files
authored
Merge pull request #422 from SimformSolutionsPvtLtd/feature/month_view_show_weekends_flag
feat: Fixes issue #385: Add `showWeekends` flag in month view
2 parents cc99a0e + d13fa9a commit 095ede2

File tree

7 files changed

+129
-63
lines changed

7 files changed

+129
-63
lines changed

CHANGELOG.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
# [1.4.0](https://github.com/SimformSolutionsPvtLtd/flutter_calendar_view/tree/1.4.0)
2+
- Adds `showWeekends` flag in month view to hide & show weekends view.
3+
Default is `showWeekends = true` shows all weekdays. [#385](https://github.com/SimformSolutionsPvtLtd/flutter_calendar_view/issues/385)
4+
- Events are now hidden for days not in the current month when hideDaysNotInMonth = true
5+
16
# [1.3.0 - 12 Nov 2024](https://github.com/SimformSolutionsPvtLtd/flutter_calendar_view/tree/1.3.0)
27

38
- Fixes full day event position when fullHeaderTitle is empty.
@@ -199,4 +204,4 @@
199204

200205
# [0.0.1 - 26 Aug 2021](https://github.com/SimformSolutionsPvtLtd/flutter_calendar_view/tree/0.0.1)
201206

202-
- Initial release
207+
- Initial release

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ MonthView(
154154
headerBuilder: MonthHeader.hidden, // To hide month header
155155
showWeekTileBorder: false, // To show or hide header border
156156
hideDaysNotInMonth: true, // To hide days or cell that are not in current month
157+
showWeekends: false, // To hide weekends default value is true
157158
);
158159
```
159160

example/lib/widgets/month_view_widget.dart

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,10 @@ class MonthViewWidget extends StatelessWidget {
1818
return MonthView(
1919
key: state,
2020
width: width,
21-
hideDaysNotInMonth: false,
21+
showWeekends: false,
22+
startDay: WeekDays.friday,
23+
useAvailableVerticalSpace: true,
24+
hideDaysNotInMonth: true,
2225
onEventTap: (event, date) {
2326
Navigator.of(context).push(
2427
MaterialPageRoute(

example/lib/widgets/week_view_widget.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ class WeekViewWidget extends StatelessWidget {
1414
return WeekView(
1515
key: state,
1616
width: width,
17+
showWeekends: false,
1718
showLiveTimeLineInAllDays: true,
1819
eventArranger: SideEventArranger(maxWidth: 30),
1920
timeLineWidth: 65,

lib/src/extensions.dart

Lines changed: 42 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,10 @@ extension DateTimeExtensions on DateTime {
5252
/// will return dates
5353
/// [6,7,8,9,10,11,12]
5454
/// Where on 6th there will be monday and on 12th there will be Sunday
55-
List<DateTime> datesOfWeek({WeekDays start = WeekDays.monday}) {
55+
List<DateTime> datesOfWeek({
56+
WeekDays start = WeekDays.monday,
57+
bool showWeekEnds = true,
58+
}) {
5659
// Here %7 ensure that we do not subtract >6 and <0 days.
5760
// Initial formula is,
5861
// difference = (weekday - startInt)%7
@@ -63,16 +66,19 @@ extension DateTimeExtensions on DateTime {
6366
//
6467
final startDay =
6568
DateTime(year, month, day - (weekday - start.index - 1) % 7);
66-
67-
return [
68-
startDay,
69-
DateTime(startDay.year, startDay.month, startDay.day + 1),
70-
DateTime(startDay.year, startDay.month, startDay.day + 2),
71-
DateTime(startDay.year, startDay.month, startDay.day + 3),
72-
DateTime(startDay.year, startDay.month, startDay.day + 4),
73-
DateTime(startDay.year, startDay.month, startDay.day + 5),
74-
DateTime(startDay.year, startDay.month, startDay.day + 6),
75-
];
69+
// Generate weekdays with weekends or without weekends
70+
final days = List.generate(
71+
7,
72+
(index) => DateTime(startDay.year, startDay.month, startDay.day + index),
73+
)
74+
.where(
75+
(date) =>
76+
showWeekEnds ||
77+
(date.weekday != DateTime.saturday &&
78+
date.weekday != DateTime.sunday),
79+
)
80+
.toList();
81+
return days;
7682
}
7783

7884
/// Returns the first date of week containing the current date
@@ -87,11 +93,33 @@ extension DateTimeExtensions on DateTime {
8793
/// All the dates are week based that means it will return array of size 42
8894
/// which will contain 6 weeks that is the maximum number of weeks a month
8995
/// can have.
90-
List<DateTime> datesOfMonths({WeekDays startDay = WeekDays.monday}) {
96+
///
97+
/// It excludes week if `hideDaysNotInMonth` is set true and
98+
/// if all dates in week comes in next month then it will excludes that week.
99+
List<DateTime> datesOfMonths({
100+
WeekDays startDay = WeekDays.monday,
101+
bool hideDaysNotInMonth = false,
102+
bool showWeekends = true,
103+
}) {
91104
final monthDays = <DateTime>[];
105+
// Start is the first weekday for each week in a month
92106
for (var i = 1, start = 1; i < 7; i++, start += 7) {
93-
monthDays
94-
.addAll(DateTime(year, month, start).datesOfWeek(start: startDay));
107+
final datesInWeek =
108+
DateTime(year, month, start).datesOfWeek(start: startDay).where(
109+
(day) =>
110+
showWeekends ||
111+
(day.weekday != DateTime.saturday &&
112+
day.weekday != DateTime.sunday),
113+
);
114+
// Check does every date of week belongs to different month
115+
final allDatesNotInCurrentMonth = datesInWeek.every((date) {
116+
return date.month != month;
117+
});
118+
// if entire row contains dates of other month then skip it
119+
if (hideDaysNotInMonth && allDatesNotInCurrentMonth) {
120+
continue;
121+
}
122+
monthDays.addAll(datesInWeek);
95123
}
96124
return monthDays;
97125
}

lib/src/month_view/month_view.dart

Lines changed: 71 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,8 @@
44

55
import 'package:flutter/material.dart';
66

7-
import '../calendar_constants.dart';
8-
import '../calendar_controller_provider.dart';
9-
import '../calendar_event_data.dart';
10-
import '../components/components.dart';
7+
import '../../calendar_view.dart';
118
import '../constants.dart';
12-
import '../enumerations.dart';
13-
import '../event_controller.dart';
14-
import '../extensions.dart';
15-
import '../style/header_style.dart';
16-
import '../typedefs.dart';
179

1810
class MonthView<T extends Object?> extends StatefulWidget {
1911
/// A function that returns a [Widget] that determines appearance of
@@ -64,6 +56,10 @@ class MonthView<T extends Object?> extends StatefulWidget {
6456
/// This method will be called when user double taps on event tile.
6557
final TileTapCallback<T>? onEventDoubleTap;
6658

59+
/// Show weekends or not.
60+
/// Default value is true.
61+
final bool showWeekends;
62+
6763
/// Builds the name of the weeks.
6864
///
6965
/// Used default week builder if null.
@@ -184,6 +180,7 @@ class MonthView<T extends Object?> extends StatefulWidget {
184180
this.maxMonth,
185181
this.controller,
186182
this.initialMonth,
183+
this.showWeekends = true,
187184
this.borderSize = 1,
188185
this.useAvailableVerticalSpace = false,
189186
this.cellAspectRatio = 0.55,
@@ -342,7 +339,10 @@ class MonthViewState<T extends Object?> extends State<MonthView<T>> {
342339
onPageChanged: _onPageChange,
343340
itemBuilder: (_, index) {
344341
final date = DateTime(_minDate.year, _minDate.month + index);
345-
final weekDays = date.datesOfWeek(start: widget.startDay);
342+
final weekDays = date.datesOfWeek(
343+
start: widget.startDay,
344+
showWeekEnds: widget.showWeekends,
345+
);
346346

347347
return Column(
348348
mainAxisSize: MainAxisSize.min,
@@ -352,7 +352,7 @@ class MonthViewState<T extends Object?> extends State<MonthView<T>> {
352352
width: _width,
353353
child: Row(
354354
children: List.generate(
355-
7,
355+
widget.showWeekends ? 7 : 5,
356356
(index) => Expanded(
357357
child: SizedBox(
358358
width: _cellWidth,
@@ -364,36 +364,45 @@ class MonthViewState<T extends Object?> extends State<MonthView<T>> {
364364
),
365365
),
366366
Expanded(
367-
child: LayoutBuilder(builder: (context, constraints) {
368-
final _cellAspectRatio =
369-
widget.useAvailableVerticalSpace
370-
? calculateCellAspectRatio(
371-
constraints.maxHeight,
372-
)
373-
: widget.cellAspectRatio;
374-
375-
return SizedBox(
376-
height: _height,
377-
width: _width,
378-
child: _MonthPageBuilder<T>(
379-
key: ValueKey(date.toIso8601String()),
380-
onCellTap: widget.onCellTap,
381-
onDateLongPress: widget.onDateLongPress,
382-
width: _width,
383-
height: _height,
384-
controller: controller,
385-
borderColor: widget.borderColor,
386-
borderSize: widget.borderSize,
387-
cellBuilder: _cellBuilder,
388-
cellRatio: _cellAspectRatio,
389-
date: date,
390-
showBorder: widget.showBorder,
367+
child: LayoutBuilder(
368+
builder: (context, constraints) {
369+
final dates = date.datesOfMonths(
391370
startDay: widget.startDay,
392-
physics: widget.pagePhysics,
393371
hideDaysNotInMonth: widget.hideDaysNotInMonth,
394-
),
395-
);
396-
}),
372+
showWeekends: widget.showWeekends,
373+
);
374+
final _cellAspectRatio =
375+
widget.useAvailableVerticalSpace
376+
? calculateCellAspectRatio(
377+
height: constraints.maxHeight,
378+
daysInMonth: dates.length,
379+
)
380+
: widget.cellAspectRatio;
381+
382+
return SizedBox(
383+
height: _height,
384+
width: _width,
385+
child: _MonthPageBuilder<T>(
386+
key: ValueKey(date.toIso8601String()),
387+
onCellTap: widget.onCellTap,
388+
onDateLongPress: widget.onDateLongPress,
389+
width: _width,
390+
height: _height,
391+
controller: controller,
392+
borderColor: widget.borderColor,
393+
borderSize: widget.borderSize,
394+
cellBuilder: _cellBuilder,
395+
cellRatio: _cellAspectRatio,
396+
date: date,
397+
showBorder: widget.showBorder,
398+
startDay: widget.startDay,
399+
physics: widget.pagePhysics,
400+
hideDaysNotInMonth: widget.hideDaysNotInMonth,
401+
weekDays: widget.showWeekends ? 7 : 5,
402+
),
403+
);
404+
},
405+
),
397406
),
398407
],
399408
);
@@ -432,8 +441,12 @@ class MonthViewState<T extends Object?> extends State<MonthView<T>> {
432441
_height = _cellHeight * 6;
433442
}
434443

435-
double calculateCellAspectRatio(double height) {
436-
final _cellHeight = height / 6;
444+
double calculateCellAspectRatio({
445+
required double height,
446+
required int daysInMonth,
447+
}) {
448+
final rows = daysInMonth / 7;
449+
final _cellHeight = height / rows;
437450
return _cellWidth / _cellHeight;
438451
}
439452

@@ -663,6 +676,7 @@ class _MonthPageBuilder<T> extends StatelessWidget {
663676
final WeekDays startDay;
664677
final ScrollPhysics physics;
665678
final bool hideDaysNotInMonth;
679+
final int weekDays;
666680

667681
const _MonthPageBuilder({
668682
Key? key,
@@ -680,25 +694,36 @@ class _MonthPageBuilder<T> extends StatelessWidget {
680694
required this.startDay,
681695
required this.physics,
682696
required this.hideDaysNotInMonth,
697+
required this.weekDays,
683698
}) : super(key: key);
684699

685700
@override
686701
Widget build(BuildContext context) {
687-
final monthDays = date.datesOfMonths(startDay: startDay);
688-
return Container(
702+
final monthDays = date.datesOfMonths(
703+
startDay: startDay,
704+
hideDaysNotInMonth: hideDaysNotInMonth,
705+
showWeekends: weekDays == 7,
706+
);
707+
708+
// Highlight tiles which is not in current month
709+
return SizedBox(
689710
width: width,
690711
height: height,
691712
child: GridView.builder(
692713
padding: EdgeInsets.zero,
693714
physics: physics,
694715
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
695-
crossAxisCount: 7,
716+
crossAxisCount: weekDays,
696717
childAspectRatio: cellRatio,
697718
),
698-
itemCount: 42,
719+
itemCount: monthDays.length,
699720
shrinkWrap: true,
700721
itemBuilder: (context, index) {
701-
final events = controller.getEventsOnDay(monthDays[index]);
722+
// Hide events if `hideDaysNotInMonth` true
723+
final events =
724+
hideDaysNotInMonth & (monthDays[index].month != date.month)
725+
? <CalendarEventData<T>>[]
726+
: controller.getEventsOnDay(monthDays[index]);
702727
return GestureDetector(
703728
onTap: () => onCellTap?.call(events, monthDays[index]),
704729
onLongPress: () => onDateLongPress?.call(monthDays[index]),

lib/src/week_view/week_view.dart

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -514,7 +514,10 @@ class WeekViewState<T extends Object?> extends State<WeekView<T>> {
514514
itemBuilder: (_, index) {
515515
final dates = DateTime(_minDate.year, _minDate.month,
516516
_minDate.day + (index * DateTime.daysPerWeek))
517-
.datesOfWeek(start: widget.startDay);
517+
.datesOfWeek(
518+
start: widget.startDay,
519+
showWeekEnds: widget.showWeekends,
520+
);
518521

519522
return ValueListenableBuilder(
520523
valueListenable: _scrollConfiguration,

0 commit comments

Comments
 (0)