Unverified Commit 681b72c3 authored by Skandar Munir's avatar Skandar Munir Committed by GitHub

fixes Show Week Day in CupertinoDatePicker with CupertinoDatePickerMo… (#120052)

fixes Show Week Day in CupertinoDatePicker with CupertinoDatePickerMo…
parent 67797182
...@@ -81,6 +81,8 @@ class _DatePickerExampleState extends State<DatePickerExample> { ...@@ -81,6 +81,8 @@ class _DatePickerExampleState extends State<DatePickerExample> {
initialDateTime: date, initialDateTime: date,
mode: CupertinoDatePickerMode.date, mode: CupertinoDatePickerMode.date,
use24hFormat: true, use24hFormat: true,
// This shows day of week alongside day of month
showDayOfWeek: true,
// This is called when the user changes the date. // This is called when the user changes the date.
onDateTimeChanged: (DateTime newDate) { onDateTimeChanged: (DateTime newDate) {
setState(() => date = newDate); setState(() => date = newDate);
......
...@@ -18,7 +18,7 @@ void main() { ...@@ -18,7 +18,7 @@ void main() {
// Drag month, day and year wheels to change the picked date. // Drag month, day and year wheels to change the picked date.
await tester.drag(find.text('October'), _kRowOffset, touchSlopY: 0, warnIfMissed: false); // see top of file await tester.drag(find.text('October'), _kRowOffset, touchSlopY: 0, warnIfMissed: false); // see top of file
await tester.drag(find.text('26'), _kRowOffset, touchSlopY: 0, warnIfMissed: false); // see top of file await tester.drag(find.textContaining('26').last, _kRowOffset, touchSlopY: 0, warnIfMissed: false); // see top of file
await tester.drag(find.text('2016'), _kRowOffset, touchSlopY: 0, warnIfMissed: false); // see top of file await tester.drag(find.text('2016'), _kRowOffset, touchSlopY: 0, warnIfMissed: false); // see top of file
await tester.pump(); await tester.pump();
......
...@@ -275,6 +275,7 @@ class CupertinoDatePicker extends StatefulWidget { ...@@ -275,6 +275,7 @@ class CupertinoDatePicker extends StatefulWidget {
this.use24hFormat = false, this.use24hFormat = false,
this.dateOrder, this.dateOrder,
this.backgroundColor, this.backgroundColor,
this.showDayOfWeek = false
}) : initialDateTime = initialDateTime ?? DateTime.now(), }) : initialDateTime = initialDateTime ?? DateTime.now(),
assert( assert(
minuteInterval > 0 && 60 % minuteInterval == 0, minuteInterval > 0 && 60 % minuteInterval == 0,
...@@ -384,6 +385,9 @@ class CupertinoDatePicker extends StatefulWidget { ...@@ -384,6 +385,9 @@ class CupertinoDatePicker extends StatefulWidget {
/// Defaults to null, which disables background painting entirely. /// Defaults to null, which disables background painting entirely.
final Color? backgroundColor; final Color? backgroundColor;
/// Whether to to show day of week alongside day. Defaults to false.
final bool showDayOfWeek;
@override @override
State<StatefulWidget> createState() { // ignore: no_logic_in_create_state, https://github.com/flutter/flutter/issues/70499 State<StatefulWidget> createState() { // ignore: no_logic_in_create_state, https://github.com/flutter/flutter/issues/70499
// The `time` mode and `dateAndTime` mode of the picker share the time // The `time` mode and `dateAndTime` mode of the picker share the time
...@@ -404,6 +408,7 @@ class CupertinoDatePicker extends StatefulWidget { ...@@ -404,6 +408,7 @@ class CupertinoDatePicker extends StatefulWidget {
_PickerColumnType columnType, _PickerColumnType columnType,
CupertinoLocalizations localizations, CupertinoLocalizations localizations,
BuildContext context, BuildContext context,
bool showDayOfWeek
) { ) {
String longestText = ''; String longestText = '';
...@@ -443,10 +448,20 @@ class CupertinoDatePicker extends StatefulWidget { ...@@ -443,10 +448,20 @@ class CupertinoDatePicker extends StatefulWidget {
: localizations.postMeridiemAbbreviation; : localizations.postMeridiemAbbreviation;
break; break;
case _PickerColumnType.dayOfMonth: case _PickerColumnType.dayOfMonth:
int longestDayOfMonth = 1;
for (int i = 1; i <=31; i++) { for (int i = 1; i <=31; i++) {
final String dayOfMonth = localizations.datePickerDayOfMonth(i); final String dayOfMonth = localizations.datePickerDayOfMonth(i);
if (longestText.length < dayOfMonth.length) { if (longestText.length < dayOfMonth.length) {
longestText = dayOfMonth; longestText = dayOfMonth;
longestDayOfMonth = i;
}
}
if (showDayOfWeek) {
for (int wd = 1; wd < DateTime.daysPerWeek; wd++) {
final String dayOfMonth = localizations.datePickerDayOfMonth(longestDayOfMonth, wd);
if (longestText.length < dayOfMonth.length) {
longestText = dayOfMonth;
}
} }
} }
break; break;
...@@ -649,7 +664,7 @@ class _CupertinoDatePickerDateTimeState extends State<CupertinoDatePicker> { ...@@ -649,7 +664,7 @@ class _CupertinoDatePickerDateTimeState extends State<CupertinoDatePicker> {
double _getEstimatedColumnWidth(_PickerColumnType columnType) { double _getEstimatedColumnWidth(_PickerColumnType columnType) {
if (estimatedColumnWidths[columnType.index] == null) { if (estimatedColumnWidths[columnType.index] == null) {
estimatedColumnWidths[columnType.index] = estimatedColumnWidths[columnType.index] =
CupertinoDatePicker._getColumnWidth(columnType, localizations, context); CupertinoDatePicker._getColumnWidth(columnType, localizations, context, widget.showDayOfWeek);
} }
return estimatedColumnWidths[columnType.index]!; return estimatedColumnWidths[columnType.index]!;
...@@ -1151,9 +1166,9 @@ class _CupertinoDatePickerDateState extends State<CupertinoDatePicker> { ...@@ -1151,9 +1166,9 @@ class _CupertinoDatePickerDateState extends State<CupertinoDatePicker> {
} }
void _refreshEstimatedColumnWidths() { void _refreshEstimatedColumnWidths() {
estimatedColumnWidths[_PickerColumnType.dayOfMonth.index] = CupertinoDatePicker._getColumnWidth(_PickerColumnType.dayOfMonth, localizations, context); estimatedColumnWidths[_PickerColumnType.dayOfMonth.index] = CupertinoDatePicker._getColumnWidth(_PickerColumnType.dayOfMonth, localizations, context, widget.showDayOfWeek);
estimatedColumnWidths[_PickerColumnType.month.index] = CupertinoDatePicker._getColumnWidth(_PickerColumnType.month, localizations, context); estimatedColumnWidths[_PickerColumnType.month.index] = CupertinoDatePicker._getColumnWidth(_PickerColumnType.month, localizations, context, widget.showDayOfWeek);
estimatedColumnWidths[_PickerColumnType.year.index] = CupertinoDatePicker._getColumnWidth(_PickerColumnType.year, localizations, context); estimatedColumnWidths[_PickerColumnType.year.index] = CupertinoDatePicker._getColumnWidth(_PickerColumnType.year, localizations, context, widget.showDayOfWeek);
} }
// The DateTime of the last day of a given month in a given year. // The DateTime of the last day of a given month in a given year.
...@@ -1191,10 +1206,11 @@ class _CupertinoDatePickerDateState extends State<CupertinoDatePicker> { ...@@ -1191,10 +1206,11 @@ class _CupertinoDatePickerDateState extends State<CupertinoDatePicker> {
selectionOverlay: selectionOverlay, selectionOverlay: selectionOverlay,
children: List<Widget>.generate(31, (int index) { children: List<Widget>.generate(31, (int index) {
final int day = index + 1; final int day = index + 1;
final int? dayOfWeek = widget.showDayOfWeek ? DateTime(selectedYear, selectedMonth, day).weekday : null;
return itemPositioningBuilder( return itemPositioningBuilder(
context, context,
Text( Text(
localizations.datePickerDayOfMonth(day), localizations.datePickerDayOfMonth(day, dayOfWeek),
style: _themeTextStyle(context, isValid: day <= daysInCurrentMonth), style: _themeTextStyle(context, isValid: day <= daysInCurrentMonth),
), ),
); );
......
...@@ -82,12 +82,17 @@ abstract class CupertinoLocalizations { ...@@ -82,12 +82,17 @@ abstract class CupertinoLocalizations {
/// Day of month that is shown in [CupertinoDatePicker] spinner corresponding /// Day of month that is shown in [CupertinoDatePicker] spinner corresponding
/// to the given day index. /// to the given day index.
/// ///
/// If weekDay is provided then it will also show weekday name alongside the numerical day.
///
/// Examples: datePickerDayOfMonth(1) in: /// Examples: datePickerDayOfMonth(1) in:
/// ///
/// - US English: 1 /// - US English: 1
/// - Korean: 1일 /// - Korean: 1일
/// Examples: datePickerDayOfMonth(1, 1) in:
///
/// - US English: Mon 1
// The global version uses date symbols data from the intl package. // The global version uses date symbols data from the intl package.
String datePickerDayOfMonth(int dayIndex); String datePickerDayOfMonth(int dayIndex, [int? weekDay]);
/// The medium-width date format that is shown in [CupertinoDatePicker] /// The medium-width date format that is shown in [CupertinoDatePicker]
/// spinner. Abbreviates month and days of week. /// spinner. Abbreviates month and days of week.
...@@ -292,7 +297,8 @@ class DefaultCupertinoLocalizations implements CupertinoLocalizations { ...@@ -292,7 +297,8 @@ class DefaultCupertinoLocalizations implements CupertinoLocalizations {
/// function, rather than constructing this class directly. /// function, rather than constructing this class directly.
const DefaultCupertinoLocalizations(); const DefaultCupertinoLocalizations();
static const List<String> _shortWeekdays = <String>[ /// Short version of days of week.
static const List<String> shortWeekdays = <String>[
'Mon', 'Mon',
'Tue', 'Tue',
'Wed', 'Wed',
...@@ -341,7 +347,13 @@ class DefaultCupertinoLocalizations implements CupertinoLocalizations { ...@@ -341,7 +347,13 @@ class DefaultCupertinoLocalizations implements CupertinoLocalizations {
String datePickerMonth(int monthIndex) => _months[monthIndex - 1]; String datePickerMonth(int monthIndex) => _months[monthIndex - 1];
@override @override
String datePickerDayOfMonth(int dayIndex) => dayIndex.toString(); String datePickerDayOfMonth(int dayIndex, [int? weekDay]) {
if (weekDay != null) {
return ' ${shortWeekdays[weekDay - DateTime.monday]} $dayIndex ';
}
return dayIndex.toString();
}
@override @override
String datePickerHour(int hour) => hour.toString(); String datePickerHour(int hour) => hour.toString();
...@@ -362,7 +374,7 @@ class DefaultCupertinoLocalizations implements CupertinoLocalizations { ...@@ -362,7 +374,7 @@ class DefaultCupertinoLocalizations implements CupertinoLocalizations {
@override @override
String datePickerMediumDate(DateTime date) { String datePickerMediumDate(DateTime date) {
return '${_shortWeekdays[date.weekday - DateTime.monday]} ' return '${shortWeekdays[date.weekday - DateTime.monday]} '
'${_shortMonths[date.month - DateTime.january]} ' '${_shortMonths[date.month - DateTime.january]} '
'${date.day.toString().padRight(2)}'; '${date.day.toString().padRight(2)}';
} }
......
...@@ -1664,6 +1664,30 @@ void main() { ...@@ -1664,6 +1664,30 @@ void main() {
DateTime(2022, 6, 14, 3, 45), DateTime(2022, 6, 14, 3, 45),
); );
}); });
testWidgets('date picker has expected day of week', (WidgetTester tester) async {
await tester.pumpWidget(
CupertinoApp(
home: Center(
child: SizedBox(
height: 400.0,
width: 400.0,
child: CupertinoDatePicker(
mode: CupertinoDatePickerMode.date,
onDateTimeChanged: (_) { },
initialDateTime: DateTime(2018, 9, 15),
showDayOfWeek: true,
),
),
),
),
);
expect(find.text('September'), findsOneWidget);
expect(find.textContaining('Sat').last, findsOneWidget);
expect(find.textContaining('15').last, findsOneWidget);
expect(find.text('2018'), findsOneWidget);
});
} }
Widget _buildPicker({ Widget _buildPicker({
......
...@@ -12,6 +12,7 @@ void main() { ...@@ -12,6 +12,7 @@ void main() {
expect(localizations.datePickerYear(2018), isNotNull); expect(localizations.datePickerYear(2018), isNotNull);
expect(localizations.datePickerMonth(1), isNotNull); expect(localizations.datePickerMonth(1), isNotNull);
expect(localizations.datePickerDayOfMonth(1), isNotNull); expect(localizations.datePickerDayOfMonth(1), isNotNull);
expect(localizations.datePickerDayOfMonth(1, 1), isNotNull);
expect(localizations.datePickerHour(0), isNotNull); expect(localizations.datePickerHour(0), isNotNull);
expect(localizations.datePickerHourSemanticsLabel(0), isNotNull); expect(localizations.datePickerHourSemanticsLabel(0), isNotNull);
expect(localizations.datePickerMinute(0), isNotNull); expect(localizations.datePickerMinute(0), isNotNull);
......
...@@ -97,7 +97,10 @@ abstract class GlobalCupertinoLocalizations implements CupertinoLocalizations { ...@@ -97,7 +97,10 @@ abstract class GlobalCupertinoLocalizations implements CupertinoLocalizations {
} }
@override @override
String datePickerDayOfMonth(int dayIndex) { String datePickerDayOfMonth(int dayIndex, [int? weekDay]) {
if (weekDay != null) {
return ' ${DefaultCupertinoLocalizations.shortWeekdays[weekDay - DateTime.monday]} $dayIndex ';
}
// Year and month doesn't matter since we just want to day formatted. // Year and month doesn't matter since we just want to day formatted.
return _dayFormat.format(DateTime.utc(0, 0, dayIndex)); return _dayFormat.format(DateTime.utc(0, 0, dayIndex));
} }
......
...@@ -38,6 +38,11 @@ void main() { ...@@ -38,6 +38,11 @@ void main() {
expect(localizations.datePickerDayOfMonth(2), isNotNull); expect(localizations.datePickerDayOfMonth(2), isNotNull);
expect(localizations.datePickerDayOfMonth(10), isNotNull); expect(localizations.datePickerDayOfMonth(10), isNotNull);
expect(localizations.datePickerDayOfMonth(0, 1), isNotNull);
expect(localizations.datePickerDayOfMonth(1, 2), isNotNull);
expect(localizations.datePickerDayOfMonth(2, 3), isNotNull);
expect(localizations.datePickerDayOfMonth(10, 4), isNotNull);
expect(localizations.datePickerMediumDate(DateTime(2019, 3, 25)), isNotNull); expect(localizations.datePickerMediumDate(DateTime(2019, 3, 25)), isNotNull);
expect(localizations.datePickerHour(0), isNotNull); expect(localizations.datePickerHour(0), isNotNull);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment