Skip to content

Commit

Permalink
fix: 🐛 added support to keep scroll offset while scrolling in day and…
Browse files Browse the repository at this point in the history
… week view.
  • Loading branch information
apurva010 committed May 8, 2024
1 parent db4e2aa commit b529f6f
Show file tree
Hide file tree
Showing 7 changed files with 177 additions and 122 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
- # [1.1.1] (UnReleased)
- Fixed synchronization of scroll between pages in day and week view. [#186](https://github.com/SimformSolutionsPvtLtd/flutter_calendar_view/issues/186)
- Added support for double tapping gestures on any event in day, week, and month view. [#195](https://github.com/SimformSolutionsPvtLtd/flutter_calendar_view/issues/195)
- Added support to set end time of day and week view. [#298](https://github.com/SimformSolutionsPvtLtd/flutter_calendar_view/issues/298)
- Added support for horizontal scroll physics of week and month view page. [#314](https://github.com/SimformSolutionsPvtLtd/flutter_calendar_view/issues/314)
Expand Down
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,8 @@ DayView(
hourLinePainter: (lineColor, lineHeight, offset, minuteHeight, showVerticalLine, verticalLineOffset) {
return //Your custom painter.
},
dayTitleBuilder: DayHeader.hidden // To Hide day header
dayTitleBuilder: DayHeader.hidden, // To Hide day header
keepScrollOffset: true, // To maintain scroll offset while scrolling
);
```

Expand Down Expand Up @@ -218,7 +219,8 @@ WeekView(
hourLinePainter: (lineColor, lineHeight, offset, minuteHeight, showVerticalLine, verticalLineOffset) {
return //Your custom painter.
},
weekPageHeaderBuilder: WeekHeader.hidden // To hide week header
weekPageHeaderBuilder: WeekHeader.hidden, // To hide week header
keepScrollOffset: true, // To maintain scroll offset while scrolling
);
```

Expand Down
7 changes: 5 additions & 2 deletions lib/src/components/_internal_components.dart
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,12 @@ class _LiveTimeIndicatorState extends State<LiveTimeIndicator> {
/// to set dy offset of live time indicator
final startMinutes = widget.startHour * 60;

/// Check if live time is not between startHour and endHour then
/// Check if live time is not between startHour and endHour if it is then
/// don't show live time indicator
if (_currentTime.hour > widget.startHour ||
///
/// e.g. startHour : 1:00, endHour : 13:00 and live time is 17:00
/// then no need to display live time indicator on timeline
if (_currentTime.hour > widget.startHour &&
widget.endHour < _currentTime.hour) {
return SizedBox.shrink();
}
Expand Down
129 changes: 72 additions & 57 deletions lib/src/day_view/_internal_day_view_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ class InternalDayViewPage<T extends Object?> extends StatefulWidget {
/// Display full day events.
final FullDayEventBuilder<T> fullDayEventBuilder;

final ScrollController dayViewScrollController;

/// Flag to display half hours.
final bool showHalfHours;

Expand All @@ -116,17 +118,21 @@ class InternalDayViewPage<T extends Object?> extends StatefulWidget {
/// Settings for half hour indicator lines.
final HourIndicatorSettings quarterHourIndicatorSettings;

/// Scroll listener to set every page's last offset
final void Function(ScrollController) scrollListener;

/// Scroll offset of day view page.
final double scrollOffset;
/// Last scroll offset of day view page.
final double lastScrollOffset;

/// Emulate vertical line offset from hour line starts.
final double emulateVerticalOffsetBy;

/// This field will be used to set end hour for day view
final int endHour;

/// Flag to keep scrollOffset of pages on page change
final bool keepScrollOffset;

/// Defines a single day page.
const InternalDayViewPage({
Key? key,
Expand Down Expand Up @@ -154,8 +160,9 @@ class InternalDayViewPage<T extends Object?> extends StatefulWidget {
required this.minuteSlotSize,
required this.scrollNotifier,
required this.fullDayEventBuilder,
required this.dayViewScrollController,
required this.scrollListener,
this.scrollOffset = 0.0,
this.lastScrollOffset = 0.0,
required this.dayDetectorBuilder,
required this.showHalfHours,
required this.showQuarterHours,
Expand All @@ -165,6 +172,7 @@ class InternalDayViewPage<T extends Object?> extends StatefulWidget {
required this.quarterHourIndicatorSettings,
required this.emulateVerticalOffsetBy,
required this.onTileDoubleTap,
this.keepScrollOffset = false,
}) : super(key: key);

@override
Expand All @@ -179,7 +187,7 @@ class _InternalDayViewPageState<T extends Object?>
void initState() {
super.initState();
scrollController = ScrollController(
initialScrollOffset: widget.scrollOffset,
initialScrollOffset: widget.lastScrollOffset,
);
scrollController.addListener(_scrollControllerListener);
}
Expand All @@ -198,21 +206,23 @@ class _InternalDayViewPageState<T extends Object?>

@override
Widget build(BuildContext context) {
final fullDayEventList = controller.getFullDayEvent(date);
final fullDayEventList = widget.controller.getFullDayEvent(widget.date);
return Container(
height: widget.height,
width: widget.width,
child: Column(
children: [
fullDayEventList.isEmpty
? SizedBox.shrink()
:widget.fullDayEventBuilder(
widget.controller.getFullDayEvent(widget.date),
widget.date,
),
? SizedBox.shrink()
: widget.fullDayEventBuilder(
widget.controller.getFullDayEvent(widget.date),
widget.date,
),
Expanded(
child: SingleChildScrollView(
controller: scrollController,
controller: widget.keepScrollOffset
? scrollController
: widget.dayViewScrollController,
child: SizedBox(
height: widget.height,
width: widget.width,
Expand All @@ -228,60 +238,64 @@ class _InternalDayViewPageState<T extends Object?>
minuteHeight: widget.heightPerMinute,
verticalLineOffset: widget.verticalLineOffset,
showVerticalLine: widget.showVerticalLine,
lineStyle: hourIndicatorSettings.lineStyle,
dashWidth: hourIndicatorSettings.dashWidth,
dashSpaceWidth: hourIndicatorSettings.dashSpaceWidth,
emulateVerticalOffsetBy: emulateVerticalOffsetBy,
startHour: startHour,
endHour: endHour,
lineStyle: widget.hourIndicatorSettings.lineStyle,
dashWidth: widget.hourIndicatorSettings.dashWidth,
dashSpaceWidth:
widget.hourIndicatorSettings.dashSpaceWidth,
emulateVerticalOffsetBy: widget.emulateVerticalOffsetBy,
startHour: widget.startHour,
endHour: widget.endHour,
),
),
if (showHalfHours)
if (widget.showHalfHours)
CustomPaint(
size: Size(width, height),
size: Size(widget.width, widget.height),
painter: HalfHourLinePainter(
lineColor: halfHourIndicatorSettings.color,
lineHeight: halfHourIndicatorSettings.height,
offset:
timeLineWidth + halfHourIndicatorSettings.offset,
minuteHeight: heightPerMinute,
lineStyle: halfHourIndicatorSettings.lineStyle,
dashWidth: halfHourIndicatorSettings.dashWidth,
lineColor: widget.halfHourIndicatorSettings.color,
lineHeight: widget.halfHourIndicatorSettings.height,
offset: widget.timeLineWidth +
widget.halfHourIndicatorSettings.offset,
minuteHeight: widget.heightPerMinute,
lineStyle: widget.halfHourIndicatorSettings.lineStyle,
dashWidth: widget.halfHourIndicatorSettings.dashWidth,
dashSpaceWidth:
halfHourIndicatorSettings.dashSpaceWidth,
startHour: startHour,
endHour: endHour,
widget.halfHourIndicatorSettings.dashSpaceWidth,
startHour: widget.startHour,
endHour: widget.endHour,
),
),
if (showQuarterHours)
if (widget.showQuarterHours)
CustomPaint(
size: Size(width, height),
size: Size(widget.width, widget.height),
painter: QuarterHourLinePainter(
lineColor: quarterHourIndicatorSettings.color,
lineHeight: quarterHourIndicatorSettings.height,
offset: timeLineWidth +
quarterHourIndicatorSettings.offset,
minuteHeight: heightPerMinute,
lineStyle: quarterHourIndicatorSettings.lineStyle,
dashWidth: quarterHourIndicatorSettings.dashWidth,
dashSpaceWidth:
quarterHourIndicatorSettings.dashSpaceWidth,
lineColor: widget.quarterHourIndicatorSettings.color,
lineHeight:
widget.quarterHourIndicatorSettings.height,
offset: widget.timeLineWidth +
widget.quarterHourIndicatorSettings.offset,
minuteHeight: widget.heightPerMinute,
lineStyle:
widget.quarterHourIndicatorSettings.lineStyle,
dashWidth:
widget.quarterHourIndicatorSettings.dashWidth,
dashSpaceWidth: widget
.quarterHourIndicatorSettings.dashSpaceWidth,
),
),
dayDetectorBuilder(
width: width,
height: height,
heightPerMinute: heightPerMinute,
date: date,
minuteSlotSize: minuteSlotSize,
widget.dayDetectorBuilder(
width: widget.width,
height: widget.height,
heightPerMinute: widget.heightPerMinute,
date: widget.date,
minuteSlotSize: widget.minuteSlotSize,
),
Align(
alignment: Alignment.centerRight,
child: EventGenerator<T>(
height: widget.height,
date: widget.date,
onTileLongTap: onTileLongTap,
onTileDoubleTap: onTileDoubleTap,
onTileLongTap: widget.onTileLongTap,
onTileDoubleTap: widget.onTileDoubleTap,
onTileTap: widget.onTileTap,
eventArranger: widget.eventArranger,
events: widget.controller.getEventsOnDay(
Expand All @@ -291,8 +305,8 @@ class _InternalDayViewPageState<T extends Object?>
heightPerMinute: widget.heightPerMinute,
eventTileBuilder: widget.eventTileBuilder,
scrollNotifier: widget.scrollNotifier,
startHour: startHour,
endHour: endHour,
startHour: widget.startHour,
endHour: widget.endHour,
width: widget.width -
widget.timeLineWidth -
widget.hourIndicatorSettings.offset -
Expand All @@ -305,12 +319,13 @@ class _InternalDayViewPageState<T extends Object?>
timeLineBuilder: widget.timeLineBuilder,
timeLineOffset: widget.timeLineOffset,
timeLineWidth: widget.timeLineWidth,
showHalfHours: showHalfHours,
startHour: startHour,
endHour: endHour,
showQuarterHours: showQuarterHours,
showHalfHours: widget.showHalfHours,
startHour: widget.startHour,
endHour: widget.endHour,
showQuarterHours: widget.showQuarterHours,
key: ValueKey(widget.heightPerMinute),
liveTimeIndicatorSettings: liveTimeIndicatorSettings,
liveTimeIndicatorSettings:
widget.liveTimeIndicatorSettings,
),
if (widget.showLiveLine &&
widget.liveTimeIndicatorSettings.height > 0)
Expand All @@ -322,8 +337,8 @@ class _InternalDayViewPageState<T extends Object?>
height: widget.height,
heightPerMinute: widget.heightPerMinute,
timeLineWidth: widget.timeLineWidth,
startHour: startHour,
endHour: endHour,
startHour: widget.startHour,
endHour: widget.endHour,
),
),
],
Expand Down
16 changes: 12 additions & 4 deletions lib/src/day_view/day_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,9 @@ class DayView<T extends Object?> extends StatefulWidget {
/// This field will be used to set end hour for day view
final int endHour;

/// Flag to keep scrollOffset of pages on page change
final bool keepScrollOffset;

/// Main widget for day view.
const DayView({
Key? key,
Expand Down Expand Up @@ -275,6 +278,7 @@ class DayView<T extends Object?> extends StatefulWidget {
this.emulateVerticalOffsetBy = 0,
this.onEventDoubleTap,
this.endHour = Constants.hoursADay,
this.keepScrollOffset = false,
}) : assert(!(onHeaderTitleTap != null && dayTitleBuilder != null),
"can't use [onHeaderTitleTap] & [dayTitleBuilder] simultaneously"),
assert(timeLineOffset >= 0,
Expand Down Expand Up @@ -350,7 +354,7 @@ class DayViewState<T extends Object?> extends State<DayView<T>> {
@override
void initState() {
super.initState();
_lastScrollOffset = widget.scrollOffset;
_lastScrollOffset = widget.scrollOffset ?? 0.0;

_reloadCallback = _reload;
_setDateRange();
Expand Down Expand Up @@ -486,8 +490,6 @@ class DayViewState<T extends Object?> extends State<DayView<T>> {
minuteSlotSize: widget.minuteSlotSize,
scrollNotifier: _scrollConfiguration,
fullDayEventBuilder: _fullDayEventBuilder,
scrollOffset: _lastScrollOffset,
scrollListener: _scrollPageListener,
showHalfHours: widget.showHalfHours,
showQuarterHours: widget.showQuarterHours,
halfHourIndicatorSettings:
Expand All @@ -498,6 +500,10 @@ class DayViewState<T extends Object?> extends State<DayView<T>> {
_quarterHourIndicatorSettings,
emulateVerticalOffsetBy:
widget.emulateVerticalOffsetBy,
lastScrollOffset: _lastScrollOffset,
dayViewScrollController: _scrollController,
scrollListener: _scrollPageListener,
keepScrollOffset: widget.keepScrollOffset,
),
);
},
Expand Down Expand Up @@ -745,7 +751,9 @@ class DayViewState<T extends Object?> extends State<DayView<T>> {
_currentIndex = index;
});
}
animateToDuration(widget.startDuration);
if (!widget.keepScrollOffset) {
animateToDuration(widget.startDuration);
}
widget.onPageChange?.call(_currentDate, _currentIndex);
}

Expand Down
Loading

0 comments on commit b529f6f

Please sign in to comment.