New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update the cupertino picker visuals #65501
Changes from 10 commits
ca539f4
40e7766
a48fb9c
0c6606b
8da08c2
f0b0288
068003b
cdfc306
08d5eca
da630e9
0b54059
0aa1cdf
3259ff3
e59a5f4
794064e
4522ee4
3b3926d
681b0ec
77c0d54
8c96099
278b69b
42534d5
62cc79b
7050739
2290d53
1183516
2cc36ca
a3b552a
a07b636
b8d0532
796468c
28e878c
a499f46
3ae9fa7
27c26d9
4e93853
76850a6
77da94a
eafe928
bd3e38a
ce77670
f62d641
fab4b3d
70fd426
ab5855b
4a2ab13
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -58,6 +58,10 @@ void _animateColumnControllerToItem(FixedExtentScrollController controller, int | |
); | ||
} | ||
|
||
const Widget _leftMagnifier = CupertinoPickerDefaultMagnifier(useRightStyle: false,); | ||
const Widget _centerMagnifier = CupertinoPickerDefaultMagnifier(useLeftStyle: false, useRightStyle: false,); | ||
const Widget _rightMagnifier = CupertinoPickerDefaultMagnifier(useLeftStyle: false); | ||
|
||
// Lays out the date picker based on how much space each single column needs. | ||
// | ||
// Each column is a child of this delegate, indexed from 0 to number of columns - 1. | ||
|
@@ -453,7 +457,7 @@ class CupertinoDatePicker extends StatefulWidget { | |
} | ||
} | ||
|
||
typedef _ColumnBuilder = Widget Function(double offAxisFraction, TransitionBuilder itemPositioningBuilder); | ||
typedef _ColumnBuilder = Widget Function(double offAxisFraction, TransitionBuilder itemPositioningBuilder, Widget magnifier); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You missed these names here (magnifier -> selectionOverlay) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, thanks for reminding me. |
||
|
||
class _CupertinoDatePickerDateTimeState extends State<CupertinoDatePicker> { | ||
// Fraction of the farthest column's vanishing point vs its width. Eyeballed | ||
|
@@ -658,7 +662,7 @@ class _CupertinoDatePickerDateTimeState extends State<CupertinoDatePicker> { | |
} | ||
|
||
// Builds the date column. The date is displayed in medium date format (e.g. Fri Aug 31). | ||
Widget _buildMediumDatePicker(double offAxisFraction, TransitionBuilder itemPositioningBuilder) { | ||
Widget _buildMediumDatePicker(double offAxisFraction, TransitionBuilder itemPositioningBuilder, Widget magnifier) { | ||
return NotificationListener<ScrollNotification>( | ||
onNotification: (ScrollNotification notification) { | ||
if (notification is ScrollStartNotification) { | ||
|
@@ -711,6 +715,7 @@ class _CupertinoDatePickerDateTimeState extends State<CupertinoDatePicker> { | |
Text(dateText, style: _themeTextStyle(context)), | ||
); | ||
}, | ||
magnifier: magnifier, | ||
), | ||
); | ||
} | ||
|
@@ -734,7 +739,7 @@ class _CupertinoDatePickerDateTimeState extends State<CupertinoDatePicker> { | |
&& !(widget.maximumDate?.isBefore(rangeStart) ?? false); | ||
} | ||
|
||
Widget _buildHourPicker(double offAxisFraction, TransitionBuilder itemPositioningBuilder) { | ||
Widget _buildHourPicker(double offAxisFraction, TransitionBuilder itemPositioningBuilder, Widget magnifier) { | ||
return NotificationListener<ScrollNotification>( | ||
onNotification: (ScrollNotification notification) { | ||
if (notification is ScrollStartNotification) { | ||
|
@@ -794,11 +799,12 @@ class _CupertinoDatePickerDateTimeState extends State<CupertinoDatePicker> { | |
); | ||
}), | ||
looping: true, | ||
magnifier: magnifier, | ||
) | ||
); | ||
} | ||
|
||
Widget _buildMinutePicker(double offAxisFraction, TransitionBuilder itemPositioningBuilder) { | ||
Widget _buildMinutePicker(double offAxisFraction, TransitionBuilder itemPositioningBuilder, Widget magnifier) { | ||
return NotificationListener<ScrollNotification>( | ||
onNotification: (ScrollNotification notification) { | ||
if (notification is ScrollStartNotification) { | ||
|
@@ -843,11 +849,12 @@ class _CupertinoDatePickerDateTimeState extends State<CupertinoDatePicker> { | |
); | ||
}), | ||
looping: true, | ||
magnifier: magnifier, | ||
), | ||
); | ||
} | ||
|
||
Widget _buildAmPmPicker(double offAxisFraction, TransitionBuilder itemPositioningBuilder) { | ||
Widget _buildAmPmPicker(double offAxisFraction, TransitionBuilder itemPositioningBuilder, Widget magnifier) { | ||
return NotificationListener<ScrollNotification>( | ||
onNotification: (ScrollNotification notification) { | ||
if (notification is ScrollStartNotification) { | ||
|
@@ -883,6 +890,7 @@ class _CupertinoDatePickerDateTimeState extends State<CupertinoDatePicker> { | |
), | ||
); | ||
}), | ||
magnifier: magnifier, | ||
), | ||
); | ||
} | ||
|
@@ -982,17 +990,23 @@ class _CupertinoDatePickerDateTimeState extends State<CupertinoDatePicker> { | |
|
||
for (int i = 0; i < columnWidths.length; i++) { | ||
double offAxisFraction = 0.0; | ||
if (i == 0) | ||
Widget magnifier; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd do a comb for the rename everywhere |
||
if (i == 0) { | ||
offAxisFraction = -_kMaximumOffAxisFraction * textDirectionFactor; | ||
else if (i >= 2 || columnWidths.length == 2) | ||
magnifier = _leftMagnifier; | ||
} else if (i >= 2 || columnWidths.length == 2) | ||
offAxisFraction = _kMaximumOffAxisFraction * textDirectionFactor; | ||
|
||
EdgeInsets padding = const EdgeInsets.only(right: _kDatePickerPadSize); | ||
if (i == columnWidths.length - 1) | ||
if (i == columnWidths.length - 1) { | ||
padding = padding.flipped; | ||
magnifier = _rightMagnifier; | ||
} | ||
if (textDirectionFactor == -1) | ||
padding = padding.flipped; | ||
|
||
magnifier ??= _centerMagnifier; | ||
|
||
pickers.add(LayoutId( | ||
id: i, | ||
child: pickerBuilders[i]( | ||
|
@@ -1012,6 +1026,7 @@ class _CupertinoDatePickerDateTimeState extends State<CupertinoDatePicker> { | |
), | ||
); | ||
}, | ||
magnifier, | ||
), | ||
)); | ||
} | ||
|
@@ -1116,7 +1131,7 @@ class _CupertinoDatePickerDateState extends State<CupertinoDatePicker> { | |
// Let `DateTime` handle the year/month overflow. | ||
DateTime _lastDayInMonth(int year, int month) => DateTime(year, month + 1, 0); | ||
|
||
Widget _buildDayPicker(double offAxisFraction, TransitionBuilder itemPositioningBuilder) { | ||
Widget _buildDayPicker(double offAxisFraction, TransitionBuilder itemPositioningBuilder, Widget magnifier) { | ||
final int daysInCurrentMonth = _lastDayInMonth(selectedYear, selectedMonth).day; | ||
return NotificationListener<ScrollNotification>( | ||
onNotification: (ScrollNotification notification) { | ||
|
@@ -1153,11 +1168,12 @@ class _CupertinoDatePickerDateState extends State<CupertinoDatePicker> { | |
); | ||
}), | ||
looping: true, | ||
magnifier: magnifier, | ||
), | ||
); | ||
} | ||
|
||
Widget _buildMonthPicker(double offAxisFraction, TransitionBuilder itemPositioningBuilder) { | ||
Widget _buildMonthPicker(double offAxisFraction, TransitionBuilder itemPositioningBuilder, Widget magnifier) { | ||
return NotificationListener<ScrollNotification>( | ||
onNotification: (ScrollNotification notification) { | ||
if (notification is ScrollStartNotification) { | ||
|
@@ -1196,11 +1212,12 @@ class _CupertinoDatePickerDateState extends State<CupertinoDatePicker> { | |
); | ||
}), | ||
looping: true, | ||
magnifier: magnifier, | ||
), | ||
); | ||
} | ||
|
||
Widget _buildYearPicker(double offAxisFraction, TransitionBuilder itemPositioningBuilder) { | ||
Widget _buildYearPicker(double offAxisFraction, TransitionBuilder itemPositioningBuilder, Widget magnifier) { | ||
return NotificationListener<ScrollNotification>( | ||
onNotification: (ScrollNotification notification) { | ||
if (notification is ScrollStartNotification) { | ||
|
@@ -1242,6 +1259,7 @@ class _CupertinoDatePickerDateState extends State<CupertinoDatePicker> { | |
), | ||
); | ||
}, | ||
magnifier: magnifier, | ||
), | ||
); | ||
} | ||
|
@@ -1354,6 +1372,15 @@ class _CupertinoDatePickerDateState extends State<CupertinoDatePicker> { | |
if (textDirectionFactor == -1) | ||
padding = const EdgeInsets.only(left: _kDatePickerPadSize); | ||
|
||
Widget magnifier; | ||
if (i == 0) | ||
magnifier = _leftMagnifier; | ||
else if (i == columnWidths.length - 1) | ||
magnifier = _rightMagnifier; | ||
else | ||
magnifier = _centerMagnifier; | ||
|
||
|
||
pickers.add(LayoutId( | ||
id: i, | ||
child: pickerBuilders[i]( | ||
|
@@ -1371,6 +1398,7 @@ class _CupertinoDatePickerDateState extends State<CupertinoDatePicker> { | |
), | ||
); | ||
}, | ||
magnifier, | ||
), | ||
)); | ||
} | ||
|
@@ -1681,7 +1709,7 @@ class _CupertinoTimerPickerState extends State<CupertinoTimerPicker> { | |
); | ||
} | ||
|
||
Widget _buildHourPicker(EdgeInsetsDirectional additionalPadding) { | ||
Widget _buildHourPicker(EdgeInsetsDirectional additionalPadding, Widget magnifier) { | ||
return CupertinoPicker( | ||
scrollController: FixedExtentScrollController(initialItem: selectedHour), | ||
offAxisFraction: -0.5 * textDirectionFactor, | ||
|
@@ -1709,18 +1737,19 @@ class _CupertinoTimerPickerState extends State<CupertinoTimerPicker> { | |
child: _buildPickerNumberLabel(localizations.timerPickerHour(index), additionalPadding), | ||
); | ||
}), | ||
magnifier: magnifier, | ||
); | ||
} | ||
|
||
Widget _buildHourColumn(EdgeInsetsDirectional additionalPadding) { | ||
Widget _buildHourColumn(EdgeInsetsDirectional additionalPadding, Widget magnifier) { | ||
return Stack( | ||
children: <Widget>[ | ||
NotificationListener<ScrollEndNotification>( | ||
onNotification: (ScrollEndNotification notification) { | ||
setState(() { lastSelectedHour = selectedHour; }); | ||
return false; | ||
}, | ||
child: _buildHourPicker(additionalPadding), | ||
child: _buildHourPicker(additionalPadding, magnifier), | ||
), | ||
_buildLabel( | ||
localizations.timerPickerHourLabel(lastSelectedHour ?? selectedHour), | ||
|
@@ -1730,7 +1759,7 @@ class _CupertinoTimerPickerState extends State<CupertinoTimerPicker> { | |
); | ||
} | ||
|
||
Widget _buildMinutePicker(EdgeInsetsDirectional additionalPadding) { | ||
Widget _buildMinutePicker(EdgeInsetsDirectional additionalPadding, Widget magnifier) { | ||
double offAxisFraction; | ||
switch (widget.mode) { | ||
case CupertinoTimerPickerMode.hm: | ||
|
@@ -1775,18 +1804,19 @@ class _CupertinoTimerPickerState extends State<CupertinoTimerPicker> { | |
child: _buildPickerNumberLabel(localizations.timerPickerMinute(minute), additionalPadding), | ||
); | ||
}), | ||
magnifier: magnifier, | ||
); | ||
} | ||
|
||
Widget _buildMinuteColumn(EdgeInsetsDirectional additionalPadding) { | ||
Widget _buildMinuteColumn(EdgeInsetsDirectional additionalPadding, Widget magnifier) { | ||
return Stack( | ||
children: <Widget>[ | ||
NotificationListener<ScrollEndNotification>( | ||
onNotification: (ScrollEndNotification notification) { | ||
setState(() { lastSelectedMinute = selectedMinute; }); | ||
return false; | ||
}, | ||
child: _buildMinutePicker(additionalPadding), | ||
child: _buildMinutePicker(additionalPadding, magnifier), | ||
), | ||
_buildLabel( | ||
localizations.timerPickerMinuteLabel(lastSelectedMinute ?? selectedMinute), | ||
|
@@ -1796,7 +1826,7 @@ class _CupertinoTimerPickerState extends State<CupertinoTimerPicker> { | |
); | ||
} | ||
|
||
Widget _buildSecondPicker(EdgeInsetsDirectional additionalPadding) { | ||
Widget _buildSecondPicker(EdgeInsetsDirectional additionalPadding, Widget magnifier) { | ||
final double offAxisFraction = 0.5 * textDirectionFactor; | ||
|
||
return CupertinoPicker( | ||
|
@@ -1831,18 +1861,19 @@ class _CupertinoTimerPickerState extends State<CupertinoTimerPicker> { | |
child: _buildPickerNumberLabel(localizations.timerPickerSecond(second), additionalPadding), | ||
); | ||
}), | ||
magnifier: magnifier, | ||
); | ||
} | ||
|
||
Widget _buildSecondColumn(EdgeInsetsDirectional additionalPadding) { | ||
Widget _buildSecondColumn(EdgeInsetsDirectional additionalPadding, Widget magnifier) { | ||
return Stack( | ||
children: <Widget>[ | ||
NotificationListener<ScrollEndNotification>( | ||
onNotification: (ScrollEndNotification notification) { | ||
setState(() { lastSelectedSecond = selectedSecond; }); | ||
return false; | ||
}, | ||
child: _buildSecondPicker(additionalPadding), | ||
child: _buildSecondPicker(additionalPadding, magnifier), | ||
), | ||
_buildLabel( | ||
localizations.timerPickerSecondLabel(lastSelectedSecond ?? selectedSecond), | ||
|
@@ -1877,24 +1908,24 @@ class _CupertinoTimerPickerState extends State<CupertinoTimerPicker> { | |
case CupertinoTimerPickerMode.hm: | ||
// Pad the widget to make it as wide as `_kPickerWidth`. | ||
columns = <Widget>[ | ||
_buildHourColumn(const EdgeInsetsDirectional.only(start: paddingValue / 2, end: _kTimerPickerHalfColumnPadding)), | ||
_buildMinuteColumn(const EdgeInsetsDirectional.only(start: _kTimerPickerHalfColumnPadding, end: paddingValue / 2)), | ||
_buildHourColumn(const EdgeInsetsDirectional.only(start: paddingValue / 2, end: _kTimerPickerHalfColumnPadding), _leftMagnifier), | ||
_buildMinuteColumn(const EdgeInsetsDirectional.only(start: _kTimerPickerHalfColumnPadding, end: paddingValue / 2), _rightMagnifier), | ||
]; | ||
break; | ||
case CupertinoTimerPickerMode.ms: | ||
// Pad the widget to make it as wide as `_kPickerWidth`. | ||
columns = <Widget>[ | ||
_buildMinuteColumn(const EdgeInsetsDirectional.only(start: paddingValue / 2, end: _kTimerPickerHalfColumnPadding)), | ||
_buildSecondColumn(const EdgeInsetsDirectional.only(start: _kTimerPickerHalfColumnPadding, end: paddingValue / 2)), | ||
_buildMinuteColumn(const EdgeInsetsDirectional.only(start: paddingValue / 2, end: _kTimerPickerHalfColumnPadding), _leftMagnifier), | ||
_buildSecondColumn(const EdgeInsetsDirectional.only(start: _kTimerPickerHalfColumnPadding, end: paddingValue / 2), _rightMagnifier), | ||
]; | ||
break; | ||
case CupertinoTimerPickerMode.hms: | ||
const double paddingValue = _kTimerPickerHalfColumnPadding * 2; | ||
totalWidth = _kTimerPickerColumnIntrinsicWidth * 3 + 4 * _kTimerPickerHalfColumnPadding + paddingValue; | ||
columns = <Widget>[ | ||
_buildHourColumn(const EdgeInsetsDirectional.only(start: paddingValue / 2, end: _kTimerPickerHalfColumnPadding)), | ||
_buildMinuteColumn(const EdgeInsetsDirectional.only(start: _kTimerPickerHalfColumnPadding, end: _kTimerPickerHalfColumnPadding)), | ||
_buildSecondColumn(const EdgeInsetsDirectional.only(start: _kTimerPickerHalfColumnPadding, end: paddingValue / 2)), | ||
_buildHourColumn(const EdgeInsetsDirectional.only(start: paddingValue / 2, end: _kTimerPickerHalfColumnPadding), _leftMagnifier), | ||
_buildMinuteColumn(const EdgeInsetsDirectional.only(start: _kTimerPickerHalfColumnPadding, end: _kTimerPickerHalfColumnPadding), _centerMagnifier), | ||
_buildSecondColumn(const EdgeInsetsDirectional.only(start: _kTimerPickerHalfColumnPadding, end: paddingValue / 2), _rightMagnifier), | ||
]; | ||
break; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you attach a screenshot for the date picker to help review as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is what the CupertinoDatePicker looks like in action, as iOS has removed this style, so it can't be compared to native components.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can by picking wheels in xcode. But it's definitely not very obvious.