@@ -6,12 +6,19 @@ import 'package:flutter/material.dart';
66import 'package:intl/date_symbol_data_local.dart' ;
77
88class DatePicker extends StatefulWidget {
9+ /// Start Date in case user wants to show past dates
10+ /// If not provided calendar will start from the initialSelectedDate
11+ final DateTime startDate;
12+
913 /// Width of the selector
1014 final double width;
1115
1216 /// Height of the selector
1317 final double height;
1418
19+ /// DatePicker Controller
20+ final DatePickerController controller;
21+
1522 /// Text color for the selected Date
1623 final Color selectedTextColor;
1724
@@ -33,28 +40,26 @@ class DatePicker extends StatefulWidget {
3340 /// Callback function for when a different date is selected
3441 final DateChangeListener onDateChange;
3542
36- /// Start Date in case user wants to show past dates
37- /// If not provided calendar will start from the initialSelectedDate
38- final DateTime startDate;
39-
40- /// Max limit up to which the dates are shown
43+ /// Max limit up to which the dates are shown.
44+ /// Days are counted from the startDate
4145 final int daysCount;
4246
4347 /// Locale for the calendar default: en_us
4448 final String locale;
4549
4650 DatePicker (
47- this .initialSelectedDate , {
51+ this .startDate , {
4852 Key key,
49- this .width,
53+ this .width = 60 ,
5054 this .height = 80 ,
55+ this .controller,
5156 this .monthTextStyle = defaultMonthTextStyle,
5257 this .dayTextStyle = defaultDayTextStyle,
5358 this .dateTextStyle = defaultDateTextStyle,
5459 this .selectedTextColor = Colors .white,
5560 this .selectionColor = AppColors .defaultSelectionColor,
56- this .startDate ,
57- this .daysCount = 50000 ,
61+ this .initialSelectedDate ,
62+ this .daysCount = 500 ,
5863 this .onDateChange,
5964 this .locale = "en_US" ,
6065 }) : super (key: key);
@@ -66,6 +71,8 @@ class DatePicker extends StatefulWidget {
6671class _DatePickerState extends State <DatePicker > {
6772 DateTime _currentDate;
6873
74+ ScrollController _controller = ScrollController ();
75+
6976 TextStyle selectedDateStyle;
7077 TextStyle selectedMonthStyle;
7178 TextStyle selectedDayStyle;
@@ -74,9 +81,13 @@ class _DatePickerState extends State<DatePicker> {
7481 void initState () {
7582 // Init the calendar locale
7683 initializeDateFormatting (widget.locale, null );
77-
7884 // Set initial Values
7985 _currentDate = widget.initialSelectedDate;
86+
87+ if (widget.controller != null ) {
88+ widget.controller.setDatePickerState (this );
89+ }
90+
8091 this .selectedDateStyle = createTextStyle (widget.dateTextStyle);
8192 this .selectedMonthStyle = createTextStyle (widget.monthTextStyle);
8293 this .selectedDayStyle = createTextStyle (widget.dayTextStyle);
@@ -107,26 +118,24 @@ class _DatePickerState extends State<DatePicker> {
107118 child: ListView .builder (
108119 itemCount: widget.daysCount,
109120 scrollDirection: Axis .horizontal,
121+ controller: _controller,
110122 itemBuilder: (context, index) {
111123 // get the date object based on the index position
112124 // if widget.startDate is null then use the initialDateValue
113125 DateTime date;
114- if (widget.startDate != null ) {
115- DateTime _date = widget.startDate.add (Duration (days: index));
116- date = new DateTime (_date.year, _date.month, _date.day);
117- } else {
118- DateTime _date = widget.initialSelectedDate.add (Duration (days: index));
119- date = new DateTime (_date.year, _date.month, _date.day);
120- }
126+ DateTime _date = widget.startDate.add (Duration (days: index));
127+ date = new DateTime (_date.year, _date.month, _date.day);
121128
122129 // Check if this date is the one that is currently selected
123- bool isSelected = compareDate (date, _currentDate);
130+ bool isSelected = _compareDate (date, _currentDate);
124131
125132 // Return the Date Widget
126133 return DateWidget (
127134 date: date,
128- monthTextStyle: isSelected ? selectedMonthStyle : widget.monthTextStyle,
129- dateTextStyle: isSelected ? selectedDateStyle : widget.dateTextStyle,
135+ monthTextStyle:
136+ isSelected ? selectedMonthStyle : widget.monthTextStyle,
137+ dateTextStyle:
138+ isSelected ? selectedDateStyle : widget.dateTextStyle,
130139 dayTextStyle: isSelected ? selectedDayStyle : widget.dayTextStyle,
131140 width: widget.width,
132141 locale: widget.locale,
@@ -147,9 +156,59 @@ class _DatePickerState extends State<DatePicker> {
147156 );
148157 }
149158
150- bool compareDate (DateTime date1, DateTime date2) {
159+ /// Helper function to compare two dates
160+ /// Returns True if both dates are the same
161+ bool _compareDate (DateTime date1, DateTime date2) {
151162 return date1.day == date2.day &&
152163 date1.month == date2.month &&
153164 date1.year == date2.year;
154165 }
155166}
167+
168+ class DatePickerController {
169+ _DatePickerState _datePickerState;
170+
171+ void setDatePickerState (_DatePickerState state) {
172+ _datePickerState = state;
173+ }
174+
175+ void jumpToSelection () {
176+ assert (_datePickerState != null ,
177+ 'DatePickerController is not attached to any DatePicker View.' );
178+
179+ // jump to the current Date
180+ _datePickerState._controller
181+ .jumpTo (_calculateDateOffset (_datePickerState._currentDate));
182+ }
183+
184+ /// This function will animate the Timeline to the currently selected Date
185+ void animateToSelection (
186+ {duration = const Duration (milliseconds: 500 ), curve = Curves .linear}) {
187+ assert (_datePickerState != null ,
188+ 'DatePickerController is not attached to any DatePicker View.' );
189+
190+ // animate to the current date
191+ _datePickerState._controller.animateTo (
192+ _calculateDateOffset (_datePickerState._currentDate),
193+ duration: duration,
194+ curve: curve);
195+ }
196+
197+ /// This function will animate to any date that is passed as a parameter
198+ /// In case a date is out of range nothing will happen
199+ void animateToDate (DateTime date,
200+ {duration = const Duration (milliseconds: 500 ), curve = Curves .linear}) {
201+ assert (_datePickerState != null ,
202+ 'DatePickerController is not attached to any DatePicker View.' );
203+
204+ _datePickerState._controller.animateTo (_calculateDateOffset (date),
205+ duration: duration, curve: curve);
206+ }
207+
208+ /// Calculate the number of pixels that needs to be scrolled to go to the
209+ /// date provided in the argument
210+ double _calculateDateOffset (DateTime date) {
211+ int offset = date.difference (_datePickerState.widget.startDate).inDays + 1 ;
212+ return (offset * _datePickerState.widget.width) + (offset * 6 );
213+ }
214+ }
0 commit comments