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
Update the cupertino picker visuals #65501
Conversation
…Color and update tertiarySystemFill.
darkElevatedColor: Color.fromARGB(61, 118, 118, 128), | ||
highContrastElevatedColor: Color.fromARGB(51, 118, 118, 128), | ||
darkHighContrastElevatedColor: Color.fromARGB(81, 118, 118, 128), | ||
color: Color.fromRGBO(118, 118, 128, 0.12), |
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.
Are these the same values as the ARGB variant?
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.
At your reminder, I rechecked this part of the color and found that in fact the color I got from the capture view hierarchy converted and matched the original color, which was my error and is now resolved.
@@ -58,6 +58,22 @@ void _animateColumnControllerToItem(FixedExtentScrollController controller, int | |||
); |
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.
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.
@@ -80,7 +80,7 @@ const TextStyle _kDefaultPickerTextStyle = TextStyle( | |||
fontFamily: '.SF Pro Display', | |||
fontSize: 21.0, | |||
fontWeight: FontWeight.w400, | |||
letterSpacing: -0.41, | |||
letterSpacing: -0.6, |
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 add a description on how you derived this value? This will help the next maintainer assess his confidence on whether that person is more rigorous or less than you are :)
e.g. extracted from Apple sketch specs or compared visually etc.
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.
To do this, I've made two comparison images that overlap the native text style version and the flutter text new and old style version, respectively.
This is a comparison of native and old version:
This is a comparison of native and new version:
It doesn't look like much of a difference, but the new style version will be a little more accurate.
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.
Sounds good, I meant could you modify the code comment above this const declaration? It'll leave some hints for the next maintainer.
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.
Maybe I'll add a comment:
// LetterSpacing sourced from iOS 14 simulator screenshots for comparison.
See also:
//
// * https://github.com/flutter/flutter/pull/65501#discussion_r486557093
What do you think?
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.
For code comments, it's ok. (I wouldn't reference /// docs to ephemeral discussions like GitHub PRs).
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.
It's updated now.
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.
Looks good to me. Thank you for the PR!
Not sure why there's no untriaged digest showing up on https://flutter-gold.skia.org/. Maybe the website needs time to catch up, I'll check again tomorrow.
const BorderRadius _rightBorderRadius = BorderRadius.horizontal(right: Radius.circular(CupertinoPicker.defaultHighlighterRadius)); | ||
|
||
|
||
Container _buildMagnifier(BuildContext context, [EdgeInsetsGeometry margin = EdgeInsets.zero, BorderRadiusGeometry borderRadius = BorderRadius.zero]) => Container( |
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.
Maybe we should expose this builder (or expose another constructor in CupertinoPicker
that allows developers to specify which side of the magnifier should have rounded corners and non-zero margins), so people can build their own multi-column pickers with ease?
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.
nit: the =>
syntax is usually reserved for one-liners: https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#consider-using--for-short-functions-and-methods
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.
I thought about doing this, but might it be easier to customize the style by providing the magnifier parameters directly?
If satisfied with the convenience of creating multi-column pickers, perhaps we could create a CupertinoPickerDefaulMagnifier StatelessWidget?
What do you think?
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.
Yeah having a widget for that sounds good to me, with it we can make the margin/radius constants private.
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.
The CupertinoPickerDefaultMagnifier has now been created.
@@ -193,6 +190,15 @@ class CupertinoPicker extends StatefulWidget { | |||
/// A delegate that lazily instantiates children. | |||
final ListWheelChildDelegate childDelegate; | |||
|
|||
/// the [magnifier] widget overlaid on top of [ListWheelScrollView]. |
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.
Maybe mention that the [magnifier] will be vertically centered and have the same size as the magnified centered item, and defaults to the grey rrect first introduced in iOS 14.
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.
Good point, I'm not very good at English, thanks for the advice.
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.
Do you think it's okay if I change it to this?
/// The [magnifier] widget overlaid on top of [ListWheelScrollView],
/// it will be vertically centered and will be the same size as the magnified item,
/// defaulting to the grey rrect first introduced in iOS 14.
offAxisFraction = -_kMaximumOffAxisFraction * textDirectionFactor; | ||
else if (i >= 2 || columnWidths.length == 2) | ||
magnifier = _buildMagnifier(context, _leftEdgeInsets, _leftBorderRadius); | ||
} else |
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.
nit: else if
should be on the same line?
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.
That's my formatting omission, thank you.
oh https://github.com/flutter/flutter/wiki/Writing-a-golden-file-test-for-package:flutter#first-time-contributors it looks like there's a special step for first time contributors. cc @Piinks |
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 a very clean fix. Thank you @YeungKC!
Just a few more comments. Generally, I'd rename magnifier
to selectionOverlay
everywhere (since we don't know if useMagnifier
is true and what users are going to put in there).
Once address, let's wait for the golden image to come in, then we can merge.
@@ -80,7 +80,7 @@ const TextStyle _kDefaultPickerTextStyle = TextStyle( | |||
fontFamily: '.SF Pro Display', | |||
fontSize: 21.0, | |||
fontWeight: FontWeight.w400, | |||
letterSpacing: -0.41, | |||
letterSpacing: -0.6, |
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.
Sounds good, I meant could you modify the code comment above this const declaration? It'll leave some hints for the next maintainer.
/// The [magnifier] widget overlaid on top of [ListWheelScrollView], | ||
/// it will be vertically centered and will be the same size as the magnified item, | ||
/// default to use [CupertinoPickerDefaultMagnifier]. |
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.
A widget overlaid on the picker to highlight the currently selected entry.
The [selectionOverlay] widget drawn above the [CupertinoPicker]'s picker wheel.
It is vertically centered in the picker and is constrained to have the same height as the
center row.
If unspecified, it defaults to a [CupertinoPickerDefaultMagnifier] which is a gray
rounded rectangle overlay in the iOS 14 style.
Word wrap as needed. In general, documentation need a 1 line summary (which is what appears when you hover over a field in IDEs' popup hints).
I wouldn't mention ListWheelScrollView here since it's an implementation detail of this API and users probably won't know what it is.
/// The [magnifier] widget overlaid on top of [ListWheelScrollView], | ||
/// it will be vertically centered and will be the same size as the magnified item, | ||
/// default to use [CupertinoPickerDefaultMagnifier]. | ||
final Widget magnifier; |
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.
I'd rename this selectionOverlay
. A 'magnifier' is what it does, not what it is. We don't know what it's going to do if the user is free to specify anything they want here.
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.
Thank you, I've solved this now.
@@ -125,6 +121,7 @@ class CupertinoPicker extends StatefulWidget { | |||
@required this.onSelectedItemChanged, | |||
@required IndexedWidgetBuilder itemBuilder, | |||
int childCount, | |||
this.magnifier, |
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.
The general pattern is to have a default value here (e.g. this.magnifier = const CupertinoPickerDefaultMagnifier()
) rather than filling it in in the state. This way, you can actually specify null as an intended value (to not draw anything there if users want).
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 was my mistake, thank you, and is now resolved.
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.
It's not a mistake :) We didn't really document this pattern clearly.
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.
But this is a best way.
@@ -313,6 +310,57 @@ class _CupertinoPickerState extends State<CupertinoPicker> { | |||
} | |||
} | |||
|
|||
/// An picker default magnifier, grey rrect first introduced in iOS 14 |
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.
A default selection overlay for [CupertinoPicker]s.
It draws a gray rounded rectangle to match the picker visuals introduced in iOS 14
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.
Thank you, it's updated now.
/// An picker default magnifier, grey rrect first introduced in iOS 14 | ||
class CupertinoPickerDefaultMagnifier extends StatelessWidget { | ||
|
||
/// Create a magnifier, it can be easily configured with the default style. |
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.
Don't editorialize or use subjective adjectives. Just state what it does.
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.
The api doc has been updated and has a more detailed description of the arguments.
/// The color to fill in the background of the magnifier, Support for using [CupertinoDynamicColor]. | ||
final Color background; | ||
|
||
/// default margin of the 'magnifier'. |
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.
Use complete sentences for all documentations (e.g. capitalize first letter).
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.
That was my mistake and it's now resolved.
const CupertinoPickerDefaultMagnifier({ | ||
Key key, | ||
this.background = CupertinoColors.tertiarySystemFill, | ||
this.useLeftStyle = true, |
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.
Could be more self-descriptive. Maybe capLeftEdge
?
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.
It's a good name, I've been thinking about naming it for a long time.... Thank you! ~~ It's been updated now.
@@ -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 comment
The 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 comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, thanks for reminding me.
@@ -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 comment
The reason will be displayed to describe this comment to others. Learn more.
I'd do a comb for the rename everywhere
…ino-picker-visuals
Before I updated, I found out about TimerPicker golden tests missing the default fontSize value, so I got unexpected results. btw, in the original test, the local test couldn't output the gold file, but here it does: https://flutter-gold.skia.org/detail?test=cupertino.timer_picker_test.datetime.initial&digest=ff6ad81d5189b693156e3501a20a5d7f |
I've approved the rest of the goldens that match expectations from the last commit. Though I'm still seeing 3 diffs that are overflowing in https://flutter-gold.skia.org/search?crs=github&fdiffmax=-1&fref=false&frgbamax=255&frgbamin=0&head=true&include=false&issue=65501&limit=50&master=false&match=name&metric=combined&neg=false&offset=0&pos=false&query=source_type%3Dflutter&sort=desc&unt=true |
I know, but I'm not sure why it's not the same as my local test results and if I can re-run the test generation? |
Sorry that this process is taking longer with the tests. Let us poke at it a bit more for a day. If we can't figure it out, I'll ask you to remove the |
Thank you for your follow-up, I believe this is worth the wait. |
…ino-picker-visuals
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.
@xster it looks like you triaged the images on https://flutter-gold.skia.org/triagelog, can you confirm that's all good? :)
I do not know why the Cirrus framework_tests-libraries-linux is showing a strange golden failure, I think there is another infra issue there, looking into it now.
The Linux web-tests look to be timing out due to #67454
Have you tried running it locally since the local execution was fixed? |
ya the local results are as expected. @YeungKC could I ask you to just comment out the |
This pull request is not suitable for automatic merging in its current state.
|
@Piinks don't know if it's related to #67468. The tests are indicating a Maybe there's some cross-talk with Cirrus as you're pointing out. @YeungKC could you comment out 'DatePicker golden tests' as well? Sorry for the hassle so far. I'll turn them back on after we unblock this PR. |
It is related. The failure you are seeing here has nothing to do with the dashboard, that all looks to be ok. This is a Cirrus failure. Cirrus is no longer talking to Gold, so it is failing here without a way to be resolved. This image shows only luci builds in the parameters under CI. That looks to be as expected. The cirrus build failure here can't be resolved until #67468 lands and can be patched in. An infra change added a Cirrus build without the config to talk to Gold, so it is stuck right now. |
@YeungKC sorry, I just understood what @Piinks was saying. There are 2 testing infrastructures in transition and both are running golden though only 1 is the "source of truth". |
Confirming both the rob test and the cirrus test are non-blockers. The rob test looped in files in the CL that aren't part of this PR due to merge issues. And the cirrus test is extraneous since the golden tests already ran on luci as mentioned above. Merging and then I'll turn the skipped golden back on. Thanks for your contribution and your patience on this one @YeungKC! |
This reverts commit db25441.
This is my first pr, but I underestimated the scope of changes and code requirements. I really thank you all for your patience during this process, and I have grown from it. |
Thanks for working through it too and being responsive. This is a high quality PR. Sorry for the infra issues. We're working through a migration so there's some wrinkles. Hopefully it won't happen again on your next PR :D |
Description
The following changes were made to update to an iOS 14 style picker:
Update tertiarySystemFill (That's a mistake, It's been resolved.)Update pickerTextStyle default letterSpacing
Adding magnifier parameters to the CupertinoPicker constructor method
Update the default magnifier default style
Updates magnifier styles for CupertinoDatePicker and CupertinoTimerPicker.
Tests Related to Modifying CupertinoPicker Styles
Compare with native visuals:
The CupertinoDatePicker and CupertinoTimerPicker tests still fail, and I still don't understand the similarity between the
The operating principle of the test is modified in order to pass the test.
Related Issues
Fixes #63694
Tests
I added the following tests:
Replace this with a list of the tests that you added as part of this PR. A change in behavior with no test covering it
will likely get reverted accidentally sooner or later. PRs must include tests for all changed/updated/fixed behaviors. See Test Coverage.
Checklist
Before you create this PR, confirm that it meets all requirements listed below by checking the relevant checkboxes (
[x]
). This will ensure a smooth and quick review process.///
).flutter analyze --flutter-repo
) does not report any problems on my PR.Breaking Change
Did any tests fail when you ran them? Please read Handling breaking changes.