diff --git a/packages/flutter/lib/src/material/pickers/calendar_date_picker.dart b/packages/flutter/lib/src/material/pickers/calendar_date_picker.dart index fea489fd309..af5db8265b8 100644 --- a/packages/flutter/lib/src/material/pickers/calendar_date_picker.dart +++ b/packages/flutter/lib/src/material/pickers/calendar_date_picker.dart @@ -77,6 +77,10 @@ class CalendarDatePicker extends StatefulWidget { /// [initialDate] must be between [firstDate] and [lastDate] or equal to /// one of them. /// + /// [currentDate] represents the current day (i.e. today). This + /// date will be highlighted in the day grid. If null, the date of + /// `DateTime.now()` will be used. + /// /// If [selectableDayPredicate] is non-null, it must return `true` for the /// [initialDate]. CalendarDatePicker({ @@ -84,6 +88,7 @@ class CalendarDatePicker extends StatefulWidget { @required DateTime initialDate, @required DateTime firstDate, @required DateTime lastDate, + DateTime currentDate, @required this.onDateChanged, this.onDisplayedMonthChanged, this.initialCalendarMode = DatePickerMode.day, @@ -94,6 +99,7 @@ class CalendarDatePicker extends StatefulWidget { initialDate = utils.dateOnly(initialDate), firstDate = utils.dateOnly(firstDate), lastDate = utils.dateOnly(lastDate), + currentDate = utils.dateOnly(currentDate ?? DateTime.now()), assert(onDateChanged != null), assert(initialCalendarMode != null), super(key: key) { @@ -124,6 +130,9 @@ class CalendarDatePicker extends StatefulWidget { /// The latest allowable [DateTime] that the user can select. final DateTime lastDate; + /// The [DateTime] representing today. It will be highlighted in the day grid. + final DateTime currentDate; + /// Called when the user selects a date in the picker. final ValueChanged onDateChanged; @@ -243,7 +252,7 @@ class _CalendarDatePickerState extends State { return _MonthPicker( key: _monthPickerKey, initialMonth: _currentDisplayedMonthDate, - currentDate: DateTime.now(), + currentDate: widget.currentDate, firstDate: widget.firstDate, lastDate: widget.lastDate, selectedDate: _selectedDate, @@ -256,7 +265,7 @@ class _CalendarDatePickerState extends State { padding: const EdgeInsets.only(top: _subHeaderHeight), child: _YearPicker( key: _yearPickerKey, - currentDate: DateTime.now(), + currentDate: widget.currentDate, firstDate: widget.firstDate, lastDate: widget.lastDate, initialDate: _currentDisplayedMonthDate, diff --git a/packages/flutter/lib/src/material/pickers/date_picker_dialog.dart b/packages/flutter/lib/src/material/pickers/date_picker_dialog.dart index 1d05ecf095d..48a99afc132 100644 --- a/packages/flutter/lib/src/material/pickers/date_picker_dialog.dart +++ b/packages/flutter/lib/src/material/pickers/date_picker_dialog.dart @@ -45,6 +45,10 @@ const Duration _dialogSizeAnimationDuration = Duration(milliseconds: 200); /// their dates are considered. Their time fields are ignored. They must all /// be non-null. /// +/// The [currentDate] represents the current day (i.e. today). This +/// date will be highlighted in the day grid. If null, the date of +/// `DateTime.now()` will be used. +/// /// An optional [initialEntryMode] argument can be used to display the date /// picker in the [DatePickerEntryMode.calendar] (a calendar month grid) /// or [DatePickerEntryMode.input] (a text input field) mode. @@ -93,6 +97,7 @@ Future showDatePicker({ @required DateTime initialDate, @required DateTime firstDate, @required DateTime lastDate, + DateTime currentDate, DatePickerEntryMode initialEntryMode = DatePickerEntryMode.calendar, SelectableDayPredicate selectableDayPredicate, String helpText, @@ -141,6 +146,7 @@ Future showDatePicker({ initialDate: initialDate, firstDate: firstDate, lastDate: lastDate, + currentDate: currentDate, initialEntryMode: initialEntryMode, selectableDayPredicate: selectableDayPredicate, helpText: helpText, @@ -184,6 +190,7 @@ class _DatePickerDialog extends StatefulWidget { @required DateTime initialDate, @required DateTime firstDate, @required DateTime lastDate, + DateTime currentDate, this.initialEntryMode = DatePickerEntryMode.calendar, this.selectableDayPredicate, this.cancelText, @@ -200,6 +207,7 @@ class _DatePickerDialog extends StatefulWidget { initialDate = utils.dateOnly(initialDate), firstDate = utils.dateOnly(firstDate), lastDate = utils.dateOnly(lastDate), + currentDate = utils.dateOnly(currentDate ?? DateTime.now()), assert(initialEntryMode != null), assert(initialCalendarMode != null), super(key: key) { @@ -230,6 +238,9 @@ class _DatePickerDialog extends StatefulWidget { /// The latest allowable [DateTime] that the user can select. final DateTime lastDate; + /// The [DateTime] representing today. It will be highlighted in the day grid. + final DateTime currentDate; + final DatePickerEntryMode initialEntryMode; /// Function to provide full control over which [DateTime] can be selected. @@ -382,6 +393,7 @@ class _DatePickerDialogState extends State<_DatePickerDialog> { initialDate: _selectedDate, firstDate: widget.firstDate, lastDate: widget.lastDate, + currentDate: widget.currentDate, onDateChanged: _handleDateChanged, selectableDayPredicate: widget.selectableDayPredicate, initialCalendarMode: widget.initialCalendarMode, diff --git a/packages/flutter/test/material/date_picker_test.dart b/packages/flutter/test/material/date_picker_test.dart index eba742f4849..e1cdf2eb704 100644 --- a/packages/flutter/test/material/date_picker_test.dart +++ b/packages/flutter/test/material/date_picker_test.dart @@ -5,6 +5,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; +import '../rendering/mock_canvas.dart'; import 'feedback_tester.dart'; void main() { @@ -12,6 +13,7 @@ void main() { DateTime firstDate; DateTime lastDate; DateTime initialDate; + DateTime today; SelectableDayPredicate selectableDayPredicate; DatePickerEntryMode initialEntryMode; DatePickerMode initialCalendarMode; @@ -37,6 +39,7 @@ void main() { firstDate = DateTime(2001, DateTime.january, 1); lastDate = DateTime(2031, DateTime.december, 31); initialDate = DateTime(2016, DateTime.january, 15); + today = DateTime(2016, DateTime.january, 3); selectableDayPredicate = null; initialEntryMode = DatePickerEntryMode.calendar; initialCalendarMode = DatePickerMode.day; @@ -75,6 +78,7 @@ void main() { initialDate: initialDate, firstDate: firstDate, lastDate: lastDate, + currentDate: today, selectableDayPredicate: selectableDayPredicate, initialDatePickerMode: initialCalendarMode, initialEntryMode: initialEntryMode, @@ -504,7 +508,7 @@ void main() { }); }); - testWidgets('Can select initial date picker mode', (WidgetTester tester) async { + testWidgets('Can select initial calendar picker mode', (WidgetTester tester) async { initialDate = DateTime(2014, DateTime.january, 15); initialCalendarMode = DatePickerMode.year; await prepareDatePicker(tester, (Future date) async { @@ -517,6 +521,18 @@ void main() { }); }); + testWidgets('currentDate is highlighted', (WidgetTester tester) async { + today = DateTime(2016, 1, 2); + await prepareDatePicker(tester, (Future date) async { + await tester.pump(); + const Color todayColor = Color(0xff2196f3); // default primary color + expect( + Material.of(tester.element(find.text('2'))), + // The current day should be painted with a circle outline + paints..circle(color: todayColor, style: PaintingStyle.stroke, strokeWidth: 1.0) + ); + }); + }); }); group('Input mode', () {