@@ -1012,18 +1012,6 @@ class _DatePickerHeader extends StatelessWidget {
1012
1012
}
1013
1013
}
1014
1014
1015
- /// Signature for predicating enabled dates in date range pickers.
1016
- ///
1017
- /// The [selectedStartDay] and [selectedEndDay] are the currently selected start
1018
- /// and end dates of a date range, which conditionally enables or disables each
1019
- /// date in the picker based on the user selection. (Example: in a hostel's room
1020
- /// selection, you are not able to select the end date after the next
1021
- /// non-selectable day).
1022
- ///
1023
- /// See [showDateRangePicker] , which has a [SelectableDayForRangePredicate]
1024
- /// parameter used to specify allowable days in the date range picker.
1025
- typedef SelectableDayForRangePredicate = bool Function (DateTime day, DateTime ? selectedStartDay, DateTime ? selectedEndDay);
1026
-
1027
1015
/// Shows a full screen modal dialog containing a Material Design date range
1028
1016
/// picker.
1029
1017
///
@@ -1152,8 +1140,11 @@ Future<DateTimeRange?> showDateRangePicker({
1152
1140
TextInputType keyboardType = TextInputType .datetime,
1153
1141
final Icon ? switchToInputEntryModeIcon,
1154
1142
final Icon ? switchToCalendarEntryModeIcon,
1155
- SelectableDayForRangePredicate ? selectableDayPredicate,
1156
1143
}) async {
1144
+ assert (
1145
+ initialDateRange == null || ! initialDateRange.start.isAfter (initialDateRange.end),
1146
+ "initialDateRange's start date must not be after it's end date." ,
1147
+ );
1157
1148
initialDateRange = initialDateRange == null ? null : DateUtils .datesOnly (initialDateRange);
1158
1149
firstDate = DateUtils .dateOnly (firstDate);
1159
1150
lastDate = DateUtils .dateOnly (lastDate);
@@ -1177,16 +1168,6 @@ Future<DateTimeRange?> showDateRangePicker({
1177
1168
initialDateRange == null || ! initialDateRange.end.isAfter (lastDate),
1178
1169
"initialDateRange's end date must be on or before lastDate $lastDate ." ,
1179
1170
);
1180
- assert (
1181
- initialDateRange == null || selectableDayPredicate == null ||
1182
- selectableDayPredicate (initialDateRange.start, initialDateRange.start, initialDateRange.end),
1183
- "initialDateRange's start date must be selectable." ,
1184
- );
1185
- assert (
1186
- initialDateRange == null || selectableDayPredicate == null ||
1187
- selectableDayPredicate (initialDateRange.end, initialDateRange.start, initialDateRange.end),
1188
- "initialDateRange's end date must be selectable." ,
1189
- );
1190
1171
currentDate = DateUtils .dateOnly (currentDate ?? DateTime .now ());
1191
1172
assert (debugCheckHasMaterialLocalizations (context));
1192
1173
@@ -1195,7 +1176,6 @@ Future<DateTimeRange?> showDateRangePicker({
1195
1176
firstDate: firstDate,
1196
1177
lastDate: lastDate,
1197
1178
currentDate: currentDate,
1198
- selectableDayPredicate: selectableDayPredicate,
1199
1179
initialEntryMode: initialEntryMode,
1200
1180
helpText: helpText,
1201
1181
cancelText: cancelText,
@@ -1304,7 +1284,6 @@ class DateRangePickerDialog extends StatefulWidget {
1304
1284
this .restorationId,
1305
1285
this .switchToInputEntryModeIcon,
1306
1286
this .switchToCalendarEntryModeIcon,
1307
- this .selectableDayPredicate,
1308
1287
});
1309
1288
1310
1289
/// The date range that the date range picker starts with when it opens.
@@ -1433,9 +1412,6 @@ class DateRangePickerDialog extends StatefulWidget {
1433
1412
/// {@macro flutter.material.date_picker.switchToCalendarEntryModeIcon}
1434
1413
final Icon ? switchToCalendarEntryModeIcon;
1435
1414
1436
- /// Function to provide full control over which [DateTime] can be selected.
1437
- final SelectableDayForRangePredicate ? selectableDayPredicate;
1438
-
1439
1415
@override
1440
1416
State <DateRangePickerDialog > createState () => _DateRangePickerDialogState ();
1441
1417
}
@@ -1498,14 +1474,18 @@ class _DateRangePickerDialogState extends State<DateRangePickerDialog> with Rest
1498
1474
1499
1475
case DatePickerEntryMode .input:
1500
1476
// Validate the range dates
1501
- if (_selectedStart.value != null && _selectedEnd.value != null && _selectedStart.value! .isAfter (_selectedEnd.value! )) {
1502
- _selectedEnd.value = null ;
1503
- }
1504
- if (_selectedStart.value != null && ! _isDaySelectable (_selectedStart.value! )) {
1477
+ if (_selectedStart.value != null &&
1478
+ (_selectedStart.value! .isBefore (widget.firstDate) || _selectedStart.value! .isAfter (widget.lastDate))) {
1505
1479
_selectedStart.value = null ;
1506
1480
// With no valid start date, having an end date makes no sense for the UI.
1507
1481
_selectedEnd.value = null ;
1508
- } else if (_selectedEnd.value != null && ! _isDaySelectable (_selectedEnd.value! )) {
1482
+ }
1483
+ if (_selectedEnd.value != null &&
1484
+ (_selectedEnd.value! .isBefore (widget.firstDate) || _selectedEnd.value! .isAfter (widget.lastDate))) {
1485
+ _selectedEnd.value = null ;
1486
+ }
1487
+ // If invalid range (start after end), then just use the start date
1488
+ if (_selectedStart.value != null && _selectedEnd.value != null && _selectedStart.value! .isAfter (_selectedEnd.value! )) {
1509
1489
_selectedEnd.value = null ;
1510
1490
}
1511
1491
_entryMode.value = DatePickerEntryMode .calendar;
@@ -1517,16 +1497,6 @@ class _DateRangePickerDialogState extends State<DateRangePickerDialog> with Rest
1517
1497
});
1518
1498
}
1519
1499
1520
- bool _isDaySelectable (DateTime day) {
1521
- if (day.isBefore (widget.firstDate) || day.isAfter (widget.lastDate)) {
1522
- return false ;
1523
- }
1524
- if (widget.selectableDayPredicate == null ) {
1525
- return true ;
1526
- }
1527
- return widget.selectableDayPredicate !(day, _selectedStart.value, _selectedEnd.value);
1528
- }
1529
-
1530
1500
void _handleStartDateChanged (DateTime ? date) {
1531
1501
setState (() => _selectedStart.value = date);
1532
1502
}
@@ -1565,7 +1535,6 @@ class _DateRangePickerDialogState extends State<DateRangePickerDialog> with Rest
1565
1535
selectedEndDate: _selectedEnd.value,
1566
1536
firstDate: widget.firstDate,
1567
1537
lastDate: widget.lastDate,
1568
- selectableDayPredicate: widget.selectableDayPredicate,
1569
1538
currentDate: widget.currentDate,
1570
1539
onStartDateChanged: _handleStartDateChanged,
1571
1540
onEndDateChanged: _handleEndDateChanged,
@@ -1618,7 +1587,6 @@ class _DateRangePickerDialogState extends State<DateRangePickerDialog> with Rest
1618
1587
initialEndDate: _selectedEnd.value,
1619
1588
firstDate: widget.firstDate,
1620
1589
lastDate: widget.lastDate,
1621
- selectableDayPredicate: widget.selectableDayPredicate,
1622
1590
onStartDateChanged: _handleStartDateChanged,
1623
1591
onEndDateChanged: _handleEndDateChanged,
1624
1592
autofocus: true ,
@@ -1714,15 +1682,13 @@ class _CalendarRangePickerDialog extends StatelessWidget {
1714
1682
required this .onCancel,
1715
1683
required this .confirmText,
1716
1684
required this .helpText,
1717
- required this .selectableDayPredicate,
1718
1685
this .entryModeButton,
1719
1686
});
1720
1687
1721
1688
final DateTime ? selectedStartDate;
1722
1689
final DateTime ? selectedEndDate;
1723
1690
final DateTime firstDate;
1724
1691
final DateTime lastDate;
1725
- final SelectableDayForRangePredicate ? selectableDayPredicate;
1726
1692
final DateTime ? currentDate;
1727
1693
final ValueChanged <DateTime > onStartDateChanged;
1728
1694
final ValueChanged <DateTime ?> onEndDateChanged;
@@ -1847,7 +1813,6 @@ class _CalendarRangePickerDialog extends StatelessWidget {
1847
1813
currentDate: currentDate,
1848
1814
onStartDateChanged: onStartDateChanged,
1849
1815
onEndDateChanged: onEndDateChanged,
1850
- selectableDayPredicate: selectableDayPredicate,
1851
1816
),
1852
1817
),
1853
1818
);
@@ -1873,7 +1838,6 @@ class _CalendarDateRangePicker extends StatefulWidget {
1873
1838
DateTime ? initialEndDate,
1874
1839
required DateTime firstDate,
1875
1840
required DateTime lastDate,
1876
- required this .selectableDayPredicate,
1877
1841
DateTime ? currentDate,
1878
1842
required this .onStartDateChanged,
1879
1843
required this .onEndDateChanged,
@@ -1904,9 +1868,6 @@ class _CalendarDateRangePicker extends StatefulWidget {
1904
1868
/// The latest allowable [DateTime] that the user can select.
1905
1869
final DateTime lastDate;
1906
1870
1907
- /// Function to provide full control over which [DateTime] can be selected.
1908
- final SelectableDayForRangePredicate ? selectableDayPredicate;
1909
-
1910
1871
/// The [DateTime] representing today. It will be highlighted in the day grid.
1911
1872
final DateTime currentDate;
1912
1873
@@ -1917,7 +1878,7 @@ class _CalendarDateRangePicker extends StatefulWidget {
1917
1878
final ValueChanged <DateTime ?>? onEndDateChanged;
1918
1879
1919
1880
@override
1920
- State < _CalendarDateRangePicker > createState () => _CalendarDateRangePickerState ();
1881
+ _CalendarDateRangePickerState createState () => _CalendarDateRangePickerState ();
1921
1882
}
1922
1883
1923
1884
class _CalendarDateRangePickerState extends State <_CalendarDateRangePicker > {
@@ -2020,7 +1981,6 @@ class _CalendarDateRangePickerState extends State<_CalendarDateRangePicker> {
2020
1981
lastDate: widget.lastDate,
2021
1982
displayedMonth: month,
2022
1983
onChanged: _updateSelection,
2023
- selectableDayPredicate: widget.selectableDayPredicate,
2024
1984
);
2025
1985
}
2026
1986
@@ -2409,7 +2369,6 @@ class _MonthItem extends StatefulWidget {
2409
2369
required this .firstDate,
2410
2370
required this .lastDate,
2411
2371
required this .displayedMonth,
2412
- required this .selectableDayPredicate,
2413
2372
}) : assert (! firstDate.isAfter (lastDate)),
2414
2373
assert (selectedDateStart == null || ! selectedDateStart.isBefore (firstDate)),
2415
2374
assert (selectedDateEnd == null || ! selectedDateEnd.isBefore (firstDate)),
@@ -2442,8 +2401,6 @@ class _MonthItem extends StatefulWidget {
2442
2401
/// The month whose days are displayed by this picker.
2443
2402
final DateTime displayedMonth;
2444
2403
2445
- final SelectableDayForRangePredicate ? selectableDayPredicate;
2446
-
2447
2404
@override
2448
2405
_MonthItemState createState () => _MonthItemState ();
2449
2406
}
@@ -2509,10 +2466,7 @@ class _MonthItemState extends State<_MonthItem> {
2509
2466
Widget _buildDayItem (BuildContext context, DateTime dayToBuild, int firstDayOffset, int daysInMonth) {
2510
2467
final int day = dayToBuild.day;
2511
2468
2512
- final bool isDisabled = dayToBuild.isAfter (widget.lastDate) ||
2513
- dayToBuild.isBefore (widget.firstDate) ||
2514
- widget.selectableDayPredicate != null &&
2515
- ! widget.selectableDayPredicate !(dayToBuild, widget.selectedDateStart, widget.selectedDateEnd);
2469
+ final bool isDisabled = dayToBuild.isAfter (widget.lastDate) || dayToBuild.isBefore (widget.firstDate);
2516
2470
final bool isRangeSelected = widget.selectedDateStart != null && widget.selectedDateEnd != null ;
2517
2471
final bool isSelectedDayStart = widget.selectedDateStart != null && dayToBuild.isAtSameMomentAs (widget.selectedDateStart! );
2518
2472
final bool isSelectedDayEnd = widget.selectedDateEnd != null && dayToBuild.isAtSameMomentAs (widget.selectedDateEnd! );
@@ -2754,7 +2708,7 @@ class _DayItemState extends State<_DayItem> {
2754
2708
if (widget.isSelectedDayStart || widget.isSelectedDayEnd) {
2755
2709
// The selected start and end dates gets a circle background
2756
2710
// highlight, and a contrasting text color.
2757
- itemStyle = itemStyle ? .apply (color: dayForegroundColor);
2711
+ itemStyle = textTheme.bodyMedium ? .apply (color: dayForegroundColor);
2758
2712
decoration = BoxDecoration (
2759
2713
color: dayBackgroundColor,
2760
2714
shape: BoxShape .circle,
@@ -2777,15 +2731,12 @@ class _DayItemState extends State<_DayItem> {
2777
2731
style: _HighlightPainterStyle .highlightAll,
2778
2732
textDirection: textDirection,
2779
2733
);
2780
- if (widget.isDisabled) {
2781
- itemStyle = itemStyle? .apply (color: colorScheme.onSurface.withOpacity (0.38 ));
2782
- }
2783
2734
} else if (widget.isDisabled) {
2784
- itemStyle = itemStyle ? .apply (color: colorScheme.onSurface.withOpacity (0.38 ));
2735
+ itemStyle = textTheme.bodyMedium ? .apply (color: colorScheme.onSurface.withOpacity (0.38 ));
2785
2736
} else if (widget.isToday) {
2786
2737
// The current day gets a different text color and a circle stroke
2787
2738
// border.
2788
- itemStyle = itemStyle ? .apply (color: colorScheme.primary);
2739
+ itemStyle = textTheme.bodyMedium ? .apply (color: colorScheme.primary);
2789
2740
decoration = BoxDecoration (
2790
2741
border: Border .all (color: colorScheme.primary),
2791
2742
shape: BoxShape .circle,
@@ -3071,7 +3022,6 @@ class _InputDateRangePicker extends StatefulWidget {
3071
3022
required DateTime lastDate,
3072
3023
required this .onStartDateChanged,
3073
3024
required this .onEndDateChanged,
3074
- required this .selectableDayPredicate,
3075
3025
this .helpText,
3076
3026
this .errorFormatText,
3077
3027
this .errorInvalidText,
@@ -3145,8 +3095,6 @@ class _InputDateRangePicker extends StatefulWidget {
3145
3095
/// {@macro flutter.material.datePickerDialog}
3146
3096
final TextInputType keyboardType;
3147
3097
3148
- final SelectableDayForRangePredicate ? selectableDayPredicate;
3149
-
3150
3098
@override
3151
3099
_InputDateRangePickerState createState () => _InputDateRangePickerState ();
3152
3100
}
@@ -3226,22 +3174,12 @@ class _InputDateRangePickerState extends State<_InputDateRangePicker> {
3226
3174
String ? _validateDate (DateTime ? date) {
3227
3175
if (date == null ) {
3228
3176
return widget.errorFormatText ?? MaterialLocalizations .of (context).invalidDateFormatLabel;
3229
- } else if (! _isDaySelectable ( date)) {
3177
+ } else if (date. isBefore (widget.firstDate) || date. isAfter (widget.lastDate )) {
3230
3178
return widget.errorInvalidText ?? MaterialLocalizations .of (context).dateOutOfRangeLabel;
3231
3179
}
3232
3180
return null ;
3233
3181
}
3234
3182
3235
- bool _isDaySelectable (DateTime day) {
3236
- if (day.isBefore (widget.firstDate) || day.isAfter (widget.lastDate)) {
3237
- return false ;
3238
- }
3239
- if (widget.selectableDayPredicate == null ) {
3240
- return true ;
3241
- }
3242
- return widget.selectableDayPredicate !(day, _startDate, _endDate);
3243
- }
3244
-
3245
3183
void _updateController (TextEditingController controller, String text, bool selectText) {
3246
3184
TextEditingValue textEditingValue = controller.value.copyWith (text: text);
3247
3185
if (selectText) {
0 commit comments