Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
ae24f184
Unverified
Commit
ae24f184
authored
Dec 27, 2019
by
LongCatIsLooong
Committed by
GitHub
Dec 27, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Reland 39919 CupertinoPicker (#47837)
parent
09b31a4d
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
239 additions
and
292 deletions
+239
-292
date_picker.dart
packages/flutter/lib/src/cupertino/date_picker.dart
+5
-9
picker.dart
packages/flutter/lib/src/cupertino/picker.dart
+28
-110
list_wheel_viewport.dart
packages/flutter/lib/src/rendering/list_wheel_viewport.dart
+71
-48
list_wheel_scroll_view.dart
packages/flutter/lib/src/widgets/list_wheel_scroll_view.dart
+18
-0
date_picker_test.dart
packages/flutter/test/cupertino/date_picker_test.dart
+18
-16
picker_test.dart
packages/flutter/test/cupertino/picker_test.dart
+42
-109
list_wheel_scroll_view_test.dart
...ges/flutter/test/widgets/list_wheel_scroll_view_test.dart
+57
-0
No files found.
packages/flutter/lib/src/cupertino/date_picker.dart
View file @
ae24f184
...
@@ -24,8 +24,6 @@ const double _kDatePickerPadSize = 12.0;
...
@@ -24,8 +24,6 @@ const double _kDatePickerPadSize = 12.0;
// The density of a date picker is different from a generic picker.
// The density of a date picker is different from a generic picker.
// Eyeballed from iOS.
// Eyeballed from iOS.
const
double
_kSqueeze
=
1.25
;
const
double
_kSqueeze
=
1.25
;
// Considers setting the default background color from the theme, in the future.
const
Color
_kBackgroundColor
=
CupertinoColors
.
white
;
const
TextStyle
_kDefaultPickerTextStyle
=
TextStyle
(
const
TextStyle
_kDefaultPickerTextStyle
=
TextStyle
(
letterSpacing:
-
0.83
,
letterSpacing:
-
0.83
,
...
@@ -230,12 +228,11 @@ class CupertinoDatePicker extends StatefulWidget {
...
@@ -230,12 +228,11 @@ class CupertinoDatePicker extends StatefulWidget {
this
.
maximumYear
,
this
.
maximumYear
,
this
.
minuteInterval
=
1
,
this
.
minuteInterval
=
1
,
this
.
use24hFormat
=
false
,
this
.
use24hFormat
=
false
,
this
.
backgroundColor
=
_kBackgroundColor
,
this
.
backgroundColor
,
})
:
initialDateTime
=
initialDateTime
??
DateTime
.
now
(),
})
:
initialDateTime
=
initialDateTime
??
DateTime
.
now
(),
assert
(
mode
!=
null
),
assert
(
mode
!=
null
),
assert
(
onDateTimeChanged
!=
null
),
assert
(
onDateTimeChanged
!=
null
),
assert
(
minimumYear
!=
null
),
assert
(
minimumYear
!=
null
),
assert
(
backgroundColor
!=
null
),
assert
(
assert
(
minuteInterval
>
0
&&
60
%
minuteInterval
==
0
,
minuteInterval
>
0
&&
60
%
minuteInterval
==
0
,
'minute interval is not a positive integer factor of 60'
,
'minute interval is not a positive integer factor of 60'
,
...
@@ -313,7 +310,7 @@ class CupertinoDatePicker extends StatefulWidget {
...
@@ -313,7 +310,7 @@ class CupertinoDatePicker extends StatefulWidget {
/// Background color of date picker.
/// Background color of date picker.
///
///
/// Defaults to
[CupertinoColors.white] when null
.
/// Defaults to
null, which disables background painting entirely
.
final
Color
backgroundColor
;
final
Color
backgroundColor
;
@override
@override
...
@@ -1242,7 +1239,7 @@ class CupertinoTimerPicker extends StatefulWidget {
...
@@ -1242,7 +1239,7 @@ class CupertinoTimerPicker extends StatefulWidget {
this
.
minuteInterval
=
1
,
this
.
minuteInterval
=
1
,
this
.
secondInterval
=
1
,
this
.
secondInterval
=
1
,
this
.
alignment
=
Alignment
.
center
,
this
.
alignment
=
Alignment
.
center
,
this
.
backgroundColor
=
_kBackgroundColor
,
this
.
backgroundColor
,
@required
this
.
onTimerDurationChanged
,
@required
this
.
onTimerDurationChanged
,
})
:
assert
(
mode
!=
null
),
})
:
assert
(
mode
!=
null
),
assert
(
onTimerDurationChanged
!=
null
),
assert
(
onTimerDurationChanged
!=
null
),
...
@@ -1252,7 +1249,6 @@ class CupertinoTimerPicker extends StatefulWidget {
...
@@ -1252,7 +1249,6 @@ class CupertinoTimerPicker extends StatefulWidget {
assert
(
secondInterval
>
0
&&
60
%
secondInterval
==
0
),
assert
(
secondInterval
>
0
&&
60
%
secondInterval
==
0
),
assert
(
initialTimerDuration
.
inMinutes
%
minuteInterval
==
0
),
assert
(
initialTimerDuration
.
inMinutes
%
minuteInterval
==
0
),
assert
(
initialTimerDuration
.
inSeconds
%
secondInterval
==
0
),
assert
(
initialTimerDuration
.
inSeconds
%
secondInterval
==
0
),
assert
(
backgroundColor
!=
null
),
assert
(
alignment
!=
null
),
assert
(
alignment
!=
null
),
super
(
key:
key
);
super
(
key:
key
);
...
@@ -1280,7 +1276,7 @@ class CupertinoTimerPicker extends StatefulWidget {
...
@@ -1280,7 +1276,7 @@ class CupertinoTimerPicker extends StatefulWidget {
/// Background color of timer picker.
/// Background color of timer picker.
///
///
/// Defaults to
[CupertinoColors.white] when null
.
/// Defaults to
null, which disables background painting entirely
.
final
Color
backgroundColor
;
final
Color
backgroundColor
;
@override
@override
...
@@ -1687,7 +1683,7 @@ class _CupertinoTimerPickerState extends State<CupertinoTimerPicker> {
...
@@ -1687,7 +1683,7 @@ class _CupertinoTimerPickerState extends State<CupertinoTimerPicker> {
child:
Align
(
child:
Align
(
alignment:
widget
.
alignment
,
alignment:
widget
.
alignment
,
child:
Container
(
child:
Container
(
color:
_kBackgroundColor
,
color:
CupertinoDynamicColor
.
resolve
(
widget
.
backgroundColor
,
context
)
,
width:
totalWidth
,
width:
totalWidth
,
height:
_kPickerHeight
,
height:
_kPickerHeight
,
child:
DefaultTextStyle
(
child:
DefaultTextStyle
(
...
...
packages/flutter/lib/src/cupertino/picker.dart
View file @
ae24f184
...
@@ -7,19 +7,23 @@ import 'package:flutter/rendering.dart';
...
@@ -7,19 +7,23 @@ import 'package:flutter/rendering.dart';
import
'package:flutter/services.dart'
;
import
'package:flutter/services.dart'
;
import
'package:flutter/widgets.dart'
;
import
'package:flutter/widgets.dart'
;
import
'colors.dart'
;
import
'theme.dart'
;
import
'theme.dart'
;
/// Color of the 'magnifier' lens border.
/// Color of the 'magnifier' lens border.
const
Color
_kHighlighterBorder
=
Color
(
0xFF7F7F7F
);
const
Color
_kHighlighterBorder
=
CupertinoDynamicColor
.
withBrightness
(
const
Color
_kDefaultBackground
=
Color
(
0xFFD2D4DB
);
color:
Color
(
0x33000000
),
darkColor:
Color
(
0x33FFFFFF
),
);
// Eyeballed values comparing with a native picker to produce the right
// Eyeballed values comparing with a native picker to produce the right
// curvatures and densities.
// curvatures and densities.
const
double
_kDefaultDiameterRatio
=
1.07
;
const
double
_kDefaultDiameterRatio
=
1.07
;
const
double
_kDefaultPerspective
=
0.003
;
const
double
_kDefaultPerspective
=
0.003
;
const
double
_kSqueeze
=
1.45
;
const
double
_kSqueeze
=
1.45
;
/// Opacity fraction value that hides the wheel above and below the 'magnifier'
/// lens with the same color as the background.
// Opacity fraction value that dims the wheel above and below the "magnifier"
const
double
_kForegroundScreenOpacityFraction
=
0.7
;
// lens.
const
double
_kOverAndUnderCenterOpacity
=
0.447
;
/// An iOS-styled picker.
/// An iOS-styled picker.
///
///
...
@@ -65,7 +69,7 @@ class CupertinoPicker extends StatefulWidget {
...
@@ -65,7 +69,7 @@ class CupertinoPicker extends StatefulWidget {
CupertinoPicker
({
CupertinoPicker
({
Key
key
,
Key
key
,
this
.
diameterRatio
=
_kDefaultDiameterRatio
,
this
.
diameterRatio
=
_kDefaultDiameterRatio
,
this
.
backgroundColor
=
_kDefaultBackground
,
this
.
backgroundColor
,
this
.
offAxisFraction
=
0.0
,
this
.
offAxisFraction
=
0.0
,
this
.
useMagnifier
=
false
,
this
.
useMagnifier
=
false
,
this
.
magnification
=
1.0
,
this
.
magnification
=
1.0
,
...
@@ -108,7 +112,7 @@ class CupertinoPicker extends StatefulWidget {
...
@@ -108,7 +112,7 @@ class CupertinoPicker extends StatefulWidget {
CupertinoPicker
.
builder
({
CupertinoPicker
.
builder
({
Key
key
,
Key
key
,
this
.
diameterRatio
=
_kDefaultDiameterRatio
,
this
.
diameterRatio
=
_kDefaultDiameterRatio
,
this
.
backgroundColor
=
_kDefaultBackground
,
this
.
backgroundColor
,
this
.
offAxisFraction
=
0.0
,
this
.
offAxisFraction
=
0.0
,
this
.
useMagnifier
=
false
,
this
.
useMagnifier
=
false
,
this
.
magnification
=
1.0
,
this
.
magnification
=
1.0
,
...
@@ -245,110 +249,32 @@ class _CupertinoPickerState extends State<CupertinoPicker> {
...
@@ -245,110 +249,32 @@ class _CupertinoPickerState extends State<CupertinoPicker> {
}
}
}
}
/// Makes the fade to [CupertinoPicker.backgroundColor] edge gradients.
/// Draws the magnifier borders.
Widget
_buildGradientScreen
()
{
// Because BlendMode.dstOut doesn't work correctly with BoxDecoration we
// have to just do a color blend. And a due to the way we are layering
// the magnifier and the gradient on the background, using a transparent
// background color makes the picker look odd.
if
(
widget
.
backgroundColor
!=
null
&&
widget
.
backgroundColor
.
alpha
<
255
)
return
Container
();
final
Color
widgetBackgroundColor
=
widget
.
backgroundColor
??
const
Color
(
0xFFFFFFFF
);
return
Positioned
.
fill
(
child:
IgnorePointer
(
child:
Container
(
decoration:
BoxDecoration
(
gradient:
LinearGradient
(
colors:
<
Color
>[
widgetBackgroundColor
,
widgetBackgroundColor
.
withAlpha
(
0xF2
),
widgetBackgroundColor
.
withAlpha
(
0xDD
),
widgetBackgroundColor
.
withAlpha
(
0
),
widgetBackgroundColor
.
withAlpha
(
0
),
widgetBackgroundColor
.
withAlpha
(
0xDD
),
widgetBackgroundColor
.
withAlpha
(
0xF2
),
widgetBackgroundColor
,
],
stops:
const
<
double
>[
0.0
,
0.05
,
0.09
,
0.22
,
0.78
,
0.91
,
0.95
,
1.0
,
],
begin:
Alignment
.
topCenter
,
end:
Alignment
.
bottomCenter
,
),
),
),
),
);
}
/// Makes the magnifier lens look so that the colors are normal through
/// the lens and partially grayed out around it.
Widget
_buildMagnifierScreen
()
{
Widget
_buildMagnifierScreen
()
{
final
Color
foreground
=
widget
.
backgroundColor
?.
withAlpha
(
final
Color
resolvedBorderColor
=
CupertinoDynamicColor
.
resolve
(
_kHighlighterBorder
,
context
);
(
widget
.
backgroundColor
.
alpha
*
_kForegroundScreenOpacityFraction
).
toInt
()
);
return
IgnorePointer
(
return
IgnorePointer
(
child:
Column
(
child:
Center
(
children:
<
Widget
>[
child:
Container
(
Expanded
(
decoration:
BoxDecoration
(
child:
Container
(
border:
Border
(
color:
foreground
,
top:
BorderSide
(
width:
0.0
,
color:
resolvedBorderColor
),
),
bottom:
BorderSide
(
width:
0.0
,
color:
resolvedBorderColor
),
),
Container
(
decoration:
const
BoxDecoration
(
border:
Border
(
top:
BorderSide
(
width:
0.0
,
color:
_kHighlighterBorder
),
bottom:
BorderSide
(
width:
0.0
,
color:
_kHighlighterBorder
),
),
),
constraints:
BoxConstraints
.
expand
(
height:
widget
.
itemExtent
*
widget
.
magnification
,
),
),
Expanded
(
child:
Container
(
color:
foreground
,
),
),
),
),
],
),
);
}
Widget
_buildUnderMagnifierScreen
()
{
final
Color
foreground
=
widget
.
backgroundColor
?.
withAlpha
(
(
widget
.
backgroundColor
.
alpha
*
_kForegroundScreenOpacityFraction
).
toInt
()
);
return
Column
(
children:
<
Widget
>[
Expanded
(
child:
Container
()),
Container
(
color:
foreground
,
constraints:
BoxConstraints
.
expand
(
constraints:
BoxConstraints
.
expand
(
height:
widget
.
itemExtent
*
widget
.
magnification
,
height:
widget
.
itemExtent
*
widget
.
magnification
,
),
),
),
),
Expanded
(
child:
Container
()),
],
);
}
Widget
_addBackgroundToChild
(
Widget
child
)
{
return
DecoratedBox
(
decoration:
BoxDecoration
(
color:
widget
.
backgroundColor
,
),
),
child:
child
,
);
);
}
}
@override
@override
Widget
build
(
BuildContext
context
)
{
Widget
build
(
BuildContext
context
)
{
Widget
result
=
DefaultTextStyle
(
final
Color
resolvedBackgroundColor
=
CupertinoDynamicColor
.
resolve
(
widget
.
backgroundColor
,
context
);
final
Widget
result
=
DefaultTextStyle
(
style:
CupertinoTheme
.
of
(
context
).
textTheme
.
pickerTextStyle
,
style:
CupertinoTheme
.
of
(
context
).
textTheme
.
pickerTextStyle
,
child:
Stack
(
child:
Stack
(
children:
<
Widget
>[
children:
<
Widget
>[
...
@@ -363,6 +289,7 @@ class _CupertinoPickerState extends State<CupertinoPicker> {
...
@@ -363,6 +289,7 @@ class _CupertinoPickerState extends State<CupertinoPicker> {
offAxisFraction:
widget
.
offAxisFraction
,
offAxisFraction:
widget
.
offAxisFraction
,
useMagnifier:
widget
.
useMagnifier
,
useMagnifier:
widget
.
useMagnifier
,
magnification:
widget
.
magnification
,
magnification:
widget
.
magnification
,
overAndUnderCenterOpacity:
_kOverAndUnderCenterOpacity
,
itemExtent:
widget
.
itemExtent
,
itemExtent:
widget
.
itemExtent
,
squeeze:
widget
.
squeeze
,
squeeze:
widget
.
squeeze
,
onSelectedItemChanged:
_handleSelectedItemChanged
,
onSelectedItemChanged:
_handleSelectedItemChanged
,
...
@@ -370,24 +297,15 @@ class _CupertinoPickerState extends State<CupertinoPicker> {
...
@@ -370,24 +297,15 @@ class _CupertinoPickerState extends State<CupertinoPicker> {
),
),
),
),
),
),
_buildGradientScreen
(),
_buildMagnifierScreen
(),
_buildMagnifierScreen
(),
],
],
),
),
);
);
// Adds the appropriate opacity under the magnifier if the background
// color is transparent.
return
DecoratedBox
(
if
(
widget
.
backgroundColor
!=
null
&&
widget
.
backgroundColor
.
alpha
<
255
)
{
decoration:
BoxDecoration
(
color:
resolvedBackgroundColor
),
result
=
Stack
(
child:
result
,
children:
<
Widget
>
[
);
_buildUnderMagnifierScreen
(),
_addBackgroundToChild
(
result
),
],
);
}
else
{
result
=
_addBackgroundToChild
(
result
);
}
return
result
;
}
}
}
}
...
...
packages/flutter/lib/src/rendering/list_wheel_viewport.dart
View file @
ae24f184
...
@@ -140,6 +140,7 @@ class RenderListWheelViewport
...
@@ -140,6 +140,7 @@ class RenderListWheelViewport
double
offAxisFraction
=
0
,
double
offAxisFraction
=
0
,
bool
useMagnifier
=
false
,
bool
useMagnifier
=
false
,
double
magnification
=
1
,
double
magnification
=
1
,
double
overAndUnderCenterOpacity
=
1
,
@required
double
itemExtent
,
@required
double
itemExtent
,
double
squeeze
=
1
,
double
squeeze
=
1
,
bool
clipToSize
=
true
,
bool
clipToSize
=
true
,
...
@@ -156,6 +157,8 @@ class RenderListWheelViewport
...
@@ -156,6 +157,8 @@ class RenderListWheelViewport
assert
(
useMagnifier
!=
null
),
assert
(
useMagnifier
!=
null
),
assert
(
magnification
!=
null
),
assert
(
magnification
!=
null
),
assert
(
magnification
>
0
),
assert
(
magnification
>
0
),
assert
(
overAndUnderCenterOpacity
!=
null
),
assert
(
overAndUnderCenterOpacity
>=
0
&&
overAndUnderCenterOpacity
<=
1
),
assert
(
itemExtent
!=
null
),
assert
(
itemExtent
!=
null
),
assert
(
squeeze
!=
null
),
assert
(
squeeze
!=
null
),
assert
(
squeeze
>
0
),
assert
(
squeeze
>
0
),
...
@@ -172,6 +175,7 @@ class RenderListWheelViewport
...
@@ -172,6 +175,7 @@ class RenderListWheelViewport
_offAxisFraction
=
offAxisFraction
,
_offAxisFraction
=
offAxisFraction
,
_useMagnifier
=
useMagnifier
,
_useMagnifier
=
useMagnifier
,
_magnification
=
magnification
,
_magnification
=
magnification
,
_overAndUnderCenterOpacity
=
overAndUnderCenterOpacity
,
_itemExtent
=
itemExtent
,
_itemExtent
=
itemExtent
,
_squeeze
=
squeeze
,
_squeeze
=
squeeze
,
_clipToSize
=
clipToSize
,
_clipToSize
=
clipToSize
,
...
@@ -368,6 +372,25 @@ class RenderListWheelViewport
...
@@ -368,6 +372,25 @@ class RenderListWheelViewport
markNeedsPaint
();
markNeedsPaint
();
}
}
/// {@template flutter.rendering.wheelList.overAndUnderCenterOpacity}
/// The opacity value that will be applied to the wheel that appears below and
/// above the magnifier.
///
/// The default value is 1.0, which will not change anything.
///
/// Must be greater than or equal to 0, and less than or equal to 1.
/// {@endtemplate}
double
get
overAndUnderCenterOpacity
=>
_overAndUnderCenterOpacity
;
double
_overAndUnderCenterOpacity
=
1.0
;
set
overAndUnderCenterOpacity
(
double
value
)
{
assert
(
value
!=
null
);
assert
(
value
>=
0
&&
value
<=
1
);
if
(
value
==
_overAndUnderCenterOpacity
)
return
;
_overAndUnderCenterOpacity
=
value
;
markNeedsPaint
();
}
/// {@template flutter.rendering.wheelList.itemExtent}
/// {@template flutter.rendering.wheelList.itemExtent}
/// The size of the children along the main axis. Children [RenderBox]es will
/// The size of the children along the main axis. Children [RenderBox]es will
/// be given the [BoxConstraints] of this exact size.
/// be given the [BoxConstraints] of this exact size.
...
@@ -822,20 +845,16 @@ class RenderListWheelViewport
...
@@ -822,20 +845,16 @@ class RenderListWheelViewport
// Offset that helps painting everything in the center (e.g. angle = 0).
// Offset that helps painting everything in the center (e.g. angle = 0).
final
Offset
offsetToCenter
=
Offset
(
final
Offset
offsetToCenter
=
Offset
(
untransformedPaintingCoordinates
.
dx
,
untransformedPaintingCoordinates
.
dx
,
-
_topScrollMarginExtent
);
-
_topScrollMarginExtent
,
);
if
(!
useMagnifier
)
final
bool
shouldApplyOffCenterDim
=
overAndUnderCenterOpacity
<
1
;
if
(
useMagnifier
||
shouldApplyOffCenterDim
)
{
_paintChildWithMagnifier
(
context
,
offset
,
child
,
transform
,
offsetToCenter
,
untransformedPaintingCoordinates
);
}
else
{
_paintChildCylindrically
(
context
,
offset
,
child
,
transform
,
offsetToCenter
);
_paintChildCylindrically
(
context
,
offset
,
child
,
transform
,
offsetToCenter
);
else
}
_paintChildWithMagnifier
(
context
,
offset
,
child
,
transform
,
offsetToCenter
,
untransformedPaintingCoordinates
,
);
}
}
/// Paint child with the magnifier active - the child will be rendered
/// Paint child with the magnifier active - the child will be rendered
...
@@ -878,36 +897,34 @@ class RenderListWheelViewport
...
@@ -878,36 +897,34 @@ class RenderListWheelViewport
// Clipping the part in the center.
// Clipping the part in the center.
context
.
pushClipRect
(
context
.
pushClipRect
(
false
,
needsCompositing
,
offset
,
offset
,
centerRect
,
centerRect
,
(
PaintingContext
context
,
Offset
offset
)
{
(
PaintingContext
context
,
Offset
offset
)
{
context
.
pushTransform
(
context
.
pushTransform
(
false
,
needsCompositing
,
offset
,
offset
,
_magnifyTransform
(),
_magnifyTransform
(),
(
PaintingContext
context
,
Offset
offset
)
{
(
PaintingContext
context
,
Offset
offset
)
{
context
.
paintChild
(
context
.
paintChild
(
child
,
offset
+
untransformedPaintingCoordinates
);
child
,
offset
+
untransformedPaintingCoordinates
);
});
});
});
});
// Clipping the part in either the top-half or bottom-half of the wheel.
// Clipping the part in either the top-half or bottom-half of the wheel.
context
.
pushClipRect
(
context
.
pushClipRect
(
false
,
needsCompositing
,
offset
,
offset
,
untransformedPaintingCoordinates
.
dy
<=
magnifierTopLinePosition
untransformedPaintingCoordinates
.
dy
<=
magnifierTopLinePosition
?
topHalfRect
?
topHalfRect
:
bottomHalfRect
,
:
bottomHalfRect
,
(
PaintingContext
context
,
Offset
offset
)
{
(
PaintingContext
context
,
Offset
offset
)
{
_paintChildCylindrically
(
_paintChildCylindrically
(
context
,
context
,
offset
,
offset
,
child
,
child
,
cylindricalTransform
,
cylindricalTransform
,
offsetToCenter
);
offsetToCenter
);
},
},
);
);
}
else
{
}
else
{
_paintChildCylindrically
(
_paintChildCylindrically
(
...
@@ -927,20 +944,26 @@ class RenderListWheelViewport
...
@@ -927,20 +944,26 @@ class RenderListWheelViewport
Matrix4
cylindricalTransform
,
Matrix4
cylindricalTransform
,
Offset
offsetToCenter
,
Offset
offsetToCenter
,
)
{
)
{
// Paint child cylindrically, without [overAndUnderCenterOpacity].
final
PaintingContextCallback
painter
=
(
PaintingContext
context
,
Offset
offset
)
{
context
.
paintChild
(
child
,
// Paint everything in the center (e.g. angle = 0), then transform.
offset
+
offsetToCenter
,
);
};
// Paint child cylindrically, with [overAndUnderCenterOpacity].
final
PaintingContextCallback
opacityPainter
=
(
PaintingContext
context
,
Offset
offset
)
{
context
.
pushOpacity
(
offset
,
(
overAndUnderCenterOpacity
*
255
).
round
(),
painter
);
};
context
.
pushTransform
(
context
.
pushTransform
(
// Text with TransformLayers and no cullRects currently have an issue rendering
needsCompositing
,
// https://github.com/flutter/flutter/issues/14224.
false
,
offset
,
offset
,
_centerOriginTransform
(
cylindricalTransform
),
_centerOriginTransform
(
cylindricalTransform
),
// Pre-transform painting function.
// Pre-transform painting function.
(
PaintingContext
context
,
Offset
offset
)
{
overAndUnderCenterOpacity
==
1
?
painter
:
opacityPainter
,
context
.
paintChild
(
child
,
// Paint everything in the center (e.g. angle = 0), then transform.
offset
+
offsetToCenter
,
);
},
);
);
}
}
...
...
packages/flutter/lib/src/widgets/list_wheel_scroll_view.dart
View file @
ae24f184
...
@@ -575,6 +575,7 @@ class ListWheelScrollView extends StatefulWidget {
...
@@ -575,6 +575,7 @@ class ListWheelScrollView extends StatefulWidget {
this
.
offAxisFraction
=
0.0
,
this
.
offAxisFraction
=
0.0
,
this
.
useMagnifier
=
false
,
this
.
useMagnifier
=
false
,
this
.
magnification
=
1.0
,
this
.
magnification
=
1.0
,
this
.
overAndUnderCenterOpacity
=
1.0
,
@required
this
.
itemExtent
,
@required
this
.
itemExtent
,
this
.
squeeze
=
1.0
,
this
.
squeeze
=
1.0
,
this
.
onSelectedItemChanged
,
this
.
onSelectedItemChanged
,
...
@@ -588,6 +589,8 @@ class ListWheelScrollView extends StatefulWidget {
...
@@ -588,6 +589,8 @@ class ListWheelScrollView extends StatefulWidget {
assert
(
perspective
>
0
),
assert
(
perspective
>
0
),
assert
(
perspective
<=
0.01
,
RenderListWheelViewport
.
perspectiveTooHighMessage
),
assert
(
perspective
<=
0.01
,
RenderListWheelViewport
.
perspectiveTooHighMessage
),
assert
(
magnification
>
0
),
assert
(
magnification
>
0
),
assert
(
overAndUnderCenterOpacity
!=
null
),
assert
(
overAndUnderCenterOpacity
>=
0
&&
overAndUnderCenterOpacity
<=
1
),
assert
(
itemExtent
!=
null
),
assert
(
itemExtent
!=
null
),
assert
(
itemExtent
>
0
),
assert
(
itemExtent
>
0
),
assert
(
squeeze
!=
null
),
assert
(
squeeze
!=
null
),
...
@@ -612,6 +615,7 @@ class ListWheelScrollView extends StatefulWidget {
...
@@ -612,6 +615,7 @@ class ListWheelScrollView extends StatefulWidget {
this
.
offAxisFraction
=
0.0
,
this
.
offAxisFraction
=
0.0
,
this
.
useMagnifier
=
false
,
this
.
useMagnifier
=
false
,
this
.
magnification
=
1.0
,
this
.
magnification
=
1.0
,
this
.
overAndUnderCenterOpacity
=
1.0
,
@required
this
.
itemExtent
,
@required
this
.
itemExtent
,
this
.
squeeze
=
1.0
,
this
.
squeeze
=
1.0
,
this
.
onSelectedItemChanged
,
this
.
onSelectedItemChanged
,
...
@@ -625,6 +629,8 @@ class ListWheelScrollView extends StatefulWidget {
...
@@ -625,6 +629,8 @@ class ListWheelScrollView extends StatefulWidget {
assert
(
perspective
>
0
),
assert
(
perspective
>
0
),
assert
(
perspective
<=
0.01
,
RenderListWheelViewport
.
perspectiveTooHighMessage
),
assert
(
perspective
<=
0.01
,
RenderListWheelViewport
.
perspectiveTooHighMessage
),
assert
(
magnification
>
0
),
assert
(
magnification
>
0
),
assert
(
overAndUnderCenterOpacity
!=
null
),
assert
(
overAndUnderCenterOpacity
>=
0
&&
overAndUnderCenterOpacity
<=
1
),
assert
(
itemExtent
!=
null
),
assert
(
itemExtent
!=
null
),
assert
(
itemExtent
>
0
),
assert
(
itemExtent
>
0
),
assert
(
squeeze
!=
null
),
assert
(
squeeze
!=
null
),
...
@@ -677,6 +683,9 @@ class ListWheelScrollView extends StatefulWidget {
...
@@ -677,6 +683,9 @@ class ListWheelScrollView extends StatefulWidget {
/// {@macro flutter.rendering.wheelList.magnification}
/// {@macro flutter.rendering.wheelList.magnification}
final
double
magnification
;
final
double
magnification
;
/// {@macro flutter.rendering.wheelList.overAndUnderCenterOpacity}
final
double
overAndUnderCenterOpacity
;
/// Size of each child in the main axis. Must not be null and must be
/// Size of each child in the main axis. Must not be null and must be
/// positive.
/// positive.
final
double
itemExtent
;
final
double
itemExtent
;
...
@@ -757,6 +766,7 @@ class _ListWheelScrollViewState extends State<ListWheelScrollView> {
...
@@ -757,6 +766,7 @@ class _ListWheelScrollViewState extends State<ListWheelScrollView> {
offAxisFraction:
widget
.
offAxisFraction
,
offAxisFraction:
widget
.
offAxisFraction
,
useMagnifier:
widget
.
useMagnifier
,
useMagnifier:
widget
.
useMagnifier
,
magnification:
widget
.
magnification
,
magnification:
widget
.
magnification
,
overAndUnderCenterOpacity:
widget
.
overAndUnderCenterOpacity
,
itemExtent:
widget
.
itemExtent
,
itemExtent:
widget
.
itemExtent
,
squeeze:
widget
.
squeeze
,
squeeze:
widget
.
squeeze
,
clipToSize:
widget
.
clipToSize
,
clipToSize:
widget
.
clipToSize
,
...
@@ -952,6 +962,7 @@ class ListWheelViewport extends RenderObjectWidget {
...
@@ -952,6 +962,7 @@ class ListWheelViewport extends RenderObjectWidget {
this
.
offAxisFraction
=
0.0
,
this
.
offAxisFraction
=
0.0
,
this
.
useMagnifier
=
false
,
this
.
useMagnifier
=
false
,
this
.
magnification
=
1.0
,
this
.
magnification
=
1.0
,
this
.
overAndUnderCenterOpacity
=
1.0
,
@required
this
.
itemExtent
,
@required
this
.
itemExtent
,
this
.
squeeze
=
1.0
,
this
.
squeeze
=
1.0
,
this
.
clipToSize
=
true
,
this
.
clipToSize
=
true
,
...
@@ -965,6 +976,8 @@ class ListWheelViewport extends RenderObjectWidget {
...
@@ -965,6 +976,8 @@ class ListWheelViewport extends RenderObjectWidget {
assert
(
perspective
!=
null
),
assert
(
perspective
!=
null
),
assert
(
perspective
>
0
),
assert
(
perspective
>
0
),
assert
(
perspective
<=
0.01
,
RenderListWheelViewport
.
perspectiveTooHighMessage
),
assert
(
perspective
<=
0.01
,
RenderListWheelViewport
.
perspectiveTooHighMessage
),
assert
(
overAndUnderCenterOpacity
!=
null
),
assert
(
overAndUnderCenterOpacity
>=
0
&&
overAndUnderCenterOpacity
<=
1
),
assert
(
itemExtent
!=
null
),
assert
(
itemExtent
!=
null
),
assert
(
itemExtent
>
0
),
assert
(
itemExtent
>
0
),
assert
(
squeeze
!=
null
),
assert
(
squeeze
!=
null
),
...
@@ -992,6 +1005,9 @@ class ListWheelViewport extends RenderObjectWidget {
...
@@ -992,6 +1005,9 @@ class ListWheelViewport extends RenderObjectWidget {
/// {@macro flutter.rendering.wheelList.magnification}
/// {@macro flutter.rendering.wheelList.magnification}
final
double
magnification
;
final
double
magnification
;
/// {@macro flutter.rendering.wheelList.overAndUnderCenterOpacity}
final
double
overAndUnderCenterOpacity
;
/// {@macro flutter.rendering.wheelList.itemExtent}
/// {@macro flutter.rendering.wheelList.itemExtent}
final
double
itemExtent
;
final
double
itemExtent
;
...
@@ -1027,6 +1043,7 @@ class ListWheelViewport extends RenderObjectWidget {
...
@@ -1027,6 +1043,7 @@ class ListWheelViewport extends RenderObjectWidget {
offAxisFraction:
offAxisFraction
,
offAxisFraction:
offAxisFraction
,
useMagnifier:
useMagnifier
,
useMagnifier:
useMagnifier
,
magnification:
magnification
,
magnification:
magnification
,
overAndUnderCenterOpacity:
overAndUnderCenterOpacity
,
itemExtent:
itemExtent
,
itemExtent:
itemExtent
,
squeeze:
squeeze
,
squeeze:
squeeze
,
clipToSize:
clipToSize
,
clipToSize:
clipToSize
,
...
@@ -1043,6 +1060,7 @@ class ListWheelViewport extends RenderObjectWidget {
...
@@ -1043,6 +1060,7 @@ class ListWheelViewport extends RenderObjectWidget {
..
offAxisFraction
=
offAxisFraction
..
offAxisFraction
=
offAxisFraction
..
useMagnifier
=
useMagnifier
..
useMagnifier
=
useMagnifier
..
magnification
=
magnification
..
magnification
=
magnification
..
overAndUnderCenterOpacity
=
overAndUnderCenterOpacity
..
itemExtent
=
itemExtent
..
itemExtent
=
itemExtent
..
squeeze
=
squeeze
..
squeeze
=
squeeze
..
clipToSize
=
clipToSize
..
clipToSize
=
clipToSize
...
...
packages/flutter/test/cupertino/date_picker_test.dart
View file @
ae24f184
...
@@ -115,19 +115,20 @@ void main() {
...
@@ -115,19 +115,20 @@ void main() {
);
);
final
Iterable
<
CupertinoPicker
>
pickers
=
tester
.
allWidgets
.
whereType
<
CupertinoPicker
>();
final
Iterable
<
CupertinoPicker
>
pickers
=
tester
.
allWidgets
.
whereType
<
CupertinoPicker
>();
expect
(
pickers
.
any
((
CupertinoPicker
picker
)
=>
picker
.
backgroundColor
!=
CupertinoColors
.
white
),
false
);
expect
(
pickers
.
any
((
CupertinoPicker
picker
)
=>
picker
.
backgroundColor
!=
null
),
false
);
});
});
testWidgets
(
'background color
is not
null'
,
(
WidgetTester
tester
)
async
{
testWidgets
(
'background color
can be
null'
,
(
WidgetTester
tester
)
async
{
expec
t
(
await
tester
.
pumpWidge
t
(
()
{
CupertinoApp
(
CupertinoTimerPicker
(
home:
CupertinoTimerPicker
(
onTimerDurationChanged:
(
_
)
{
},
onTimerDurationChanged:
(
_
)
{
},
backgroundColor:
null
,
backgroundColor:
null
,
);
),
},
),
throwsAssertionError
,
);
);
expect
(
tester
.
takeException
(),
isNull
);
});
});
testWidgets
(
'specified background color is applied'
,
(
WidgetTester
tester
)
async
{
testWidgets
(
'specified background color is applied'
,
(
WidgetTester
tester
)
async
{
...
@@ -316,19 +317,20 @@ void main() {
...
@@ -316,19 +317,20 @@ void main() {
);
);
final
Iterable
<
CupertinoPicker
>
pickers
=
tester
.
allWidgets
.
whereType
<
CupertinoPicker
>();
final
Iterable
<
CupertinoPicker
>
pickers
=
tester
.
allWidgets
.
whereType
<
CupertinoPicker
>();
expect
(
pickers
.
any
((
CupertinoPicker
picker
)
=>
picker
.
backgroundColor
!=
CupertinoColors
.
white
),
false
);
expect
(
pickers
.
any
((
CupertinoPicker
picker
)
=>
picker
.
backgroundColor
!=
null
),
false
);
});
});
testWidgets
(
'background color
is not
null'
,
(
WidgetTester
tester
)
async
{
testWidgets
(
'background color
can be
null'
,
(
WidgetTester
tester
)
async
{
expec
t
(
await
tester
.
pumpWidge
t
(
()
{
CupertinoApp
(
CupertinoDatePicker
(
home:
CupertinoDatePicker
(
onDateTimeChanged:
(
_
)
{
},
onDateTimeChanged:
(
_
)
{
},
backgroundColor:
null
,
backgroundColor:
null
,
);
),
},
),
throwsAssertionError
,
);
);
expect
(
tester
.
takeException
(),
isNull
);
});
});
testWidgets
(
'specified background color is applied'
,
(
WidgetTester
tester
)
async
{
testWidgets
(
'specified background color is applied'
,
(
WidgetTester
tester
)
async
{
...
...
packages/flutter/test/cupertino/picker_test.dart
View file @
ae24f184
...
@@ -8,6 +8,8 @@ import 'package:flutter/rendering.dart';
...
@@ -8,6 +8,8 @@ import 'package:flutter/rendering.dart';
import
'package:flutter/services.dart'
;
import
'package:flutter/services.dart'
;
import
'package:flutter_test/flutter_test.dart'
;
import
'package:flutter_test/flutter_test.dart'
;
import
'../rendering/mock_canvas.dart'
;
void
main
(
)
{
void
main
(
)
{
testWidgets
(
'Picker respects theme styling'
,
(
WidgetTester
tester
)
async
{
testWidgets
(
'Picker respects theme styling'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
await
tester
.
pumpWidget
(
...
@@ -95,125 +97,56 @@ void main() {
...
@@ -95,125 +97,56 @@ void main() {
});
});
});
});
group
(
'gradient'
,
()
{
testWidgets
(
'picker dark mode'
,
(
WidgetTester
tester
)
async
{
testWidgets
(
'gradient displays correctly with background color'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
const
Color
backgroundColor
=
Color
.
fromRGBO
(
255
,
0
,
0
,
1.0
);
CupertinoApp
(
await
tester
.
pumpWidget
(
theme:
const
CupertinoThemeData
(
brightness:
Brightness
.
light
),
Directionality
(
home:
Align
(
textDirection:
TextDirection
.
ltr
,
alignment:
Alignment
.
topLeft
,
child:
Align
(
child:
SizedBox
(
alignment:
Alignment
.
topLeft
,
height:
300.0
,
child:
SizedBox
(
width:
300.0
,
height:
300.0
,
child:
CupertinoPicker
(
width:
300.0
,
backgroundColor:
const
CupertinoDynamicColor
.
withBrightness
(
child:
CupertinoPicker
(
color:
Color
(
0xFF123456
),
// Set alpha channel to FF to disable under magnifier painting.
backgroundColor:
backgroundColor
,
darkColor:
Color
(
0xFF654321
),
itemExtent:
15.0
,
children:
const
<
Widget
>[
Text
(
'1'
),
Text
(
'1'
),
Text
(
'1'
),
Text
(
'1'
),
Text
(
'1'
),
Text
(
'1'
),
Text
(
'1'
),
],
onSelectedItemChanged:
(
int
i
)
{
},
),
),
itemExtent:
15.0
,
children:
const
<
Widget
>[
Text
(
'1'
),
Text
(
'1'
)],
onSelectedItemChanged:
(
int
i
)
{
},
),
),
),
),
),
),
);
),
final
Container
container
=
tester
.
firstWidget
(
find
.
byType
(
Container
));
);
final
BoxDecoration
boxDecoration
=
container
.
decoration
as
BoxDecoration
;
expect
(
boxDecoration
.
gradient
.
colors
,
<
Color
>[
backgroundColor
,
backgroundColor
.
withAlpha
(
0xF2
),
backgroundColor
.
withAlpha
(
0xDD
),
backgroundColor
.
withAlpha
(
0x00
),
backgroundColor
.
withAlpha
(
0x00
),
backgroundColor
.
withAlpha
(
0xDD
),
backgroundColor
.
withAlpha
(
0xF2
),
backgroundColor
,
]);
});
testWidgets
(
'No gradient displays with transparent background color'
,
(
WidgetTester
tester
)
async
{
expect
(
find
.
byType
(
CupertinoPicker
),
paints
..
path
(
color:
const
Color
(
0x33000000
),
style:
PaintingStyle
.
stroke
));
const
Color
backgroundColor
=
Color
.
fromRGBO
(
255
,
0
,
0
,
0.5
);
expect
(
find
.
byType
(
CupertinoPicker
),
paints
..
rect
(
color:
const
Color
(
0xFF123456
)));
await
tester
.
pumpWidget
(
Directionality
(
textDirection:
TextDirection
.
ltr
,
child:
Align
(
alignment:
Alignment
.
topLeft
,
child:
SizedBox
(
height:
300.0
,
width:
300.0
,
child:
CupertinoPicker
(
backgroundColor:
backgroundColor
,
itemExtent:
15.0
,
children:
const
<
Widget
>[
Text
(
'1'
),
Text
(
'1'
),
Text
(
'1'
),
Text
(
'1'
),
Text
(
'1'
),
Text
(
'1'
),
Text
(
'1'
),
],
onSelectedItemChanged:
(
int
i
)
{
},
),
),
),
),
);
final
DecoratedBox
decoratedBox
=
tester
.
firstWidget
(
find
.
byType
(
DecoratedBox
));
final
BoxDecoration
boxDecoration
=
decoratedBox
.
decoration
as
BoxDecoration
;
expect
(
boxDecoration
.
gradient
,
isNull
);
expect
(
boxDecoration
.
color
,
isNotNull
);
});
testWidgets
(
'gradient displays correctly with null background color'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
await
tester
.
pumpWidget
(
CupertinoApp
(
Directionality
(
theme:
const
CupertinoThemeData
(
brightness:
Brightness
.
dark
),
textDirection:
TextDirection
.
ltr
,
home:
Align
(
child:
Align
(
alignment:
Alignment
.
topLeft
,
alignment:
Alignment
.
topLeft
,
child:
SizedBox
(
child:
SizedBox
(
height:
300.0
,
height:
300.0
,
width:
300.0
,
width:
300.0
,
child:
CupertinoPicker
(
child:
CupertinoPicker
(
backgroundColor:
const
CupertinoDynamicColor
.
withBrightness
(
backgroundColor:
null
,
color:
Color
(
0xFF123456
),
itemExtent:
15.0
,
darkColor:
Color
(
0xFF654321
),
children:
const
<
Widget
>[
Text
(
'1'
),
Text
(
'1'
),
Text
(
'1'
),
Text
(
'1'
),
Text
(
'1'
),
Text
(
'1'
),
Text
(
'1'
),
],
onSelectedItemChanged:
(
int
i
)
{
},
),
),
itemExtent:
15.0
,
children:
const
<
Widget
>[
Text
(
'1'
),
Text
(
'1'
)],
onSelectedItemChanged:
(
int
i
)
{
},
),
),
),
),
),
),
);
),
// If the background color is null, the gradient color should be white.
);
const
Color
backgroundColor
=
Color
(
0xFFFFFFFF
);
final
Container
container
=
tester
.
firstWidget
(
find
.
byType
(
Container
));
expect
(
find
.
byType
(
CupertinoPicker
),
paints
..
path
(
color:
const
Color
(
0x33FFFFFF
),
style:
PaintingStyle
.
stroke
));
final
BoxDecoration
boxDecoration
=
container
.
decoration
as
BoxDecoration
;
expect
(
find
.
byType
(
CupertinoPicker
),
paints
..
rect
(
color:
const
Color
(
0xFF654321
)));
expect
(
boxDecoration
.
gradient
.
colors
,
<
Color
>[
backgroundColor
,
backgroundColor
.
withAlpha
(
0xF2
),
backgroundColor
.
withAlpha
(
0xDD
),
backgroundColor
.
withAlpha
(
0x00
),
backgroundColor
.
withAlpha
(
0x00
),
backgroundColor
.
withAlpha
(
0xDD
),
backgroundColor
.
withAlpha
(
0xF2
),
backgroundColor
,
]);
});
});
});
group
(
'scroll'
,
()
{
group
(
'scroll'
,
()
{
...
...
packages/flutter/test/widgets/list_wheel_scroll_view_test.dart
View file @
ae24f184
...
@@ -64,6 +64,63 @@ void main() {
...
@@ -64,6 +64,63 @@ void main() {
throwsAssertionError
,
throwsAssertionError
,
);
);
});
});
testWidgets
(
'ListWheelScrollView needs valid overAndUnderCenterOpacity'
,
(
WidgetTester
tester
)
async
{
expect
(
()
{
ListWheelScrollView
(
overAndUnderCenterOpacity:
null
,
itemExtent:
20.0
,
children:
<
Widget
>[
Container
()],
);
},
throwsAssertionError
,
);
expect
(
()
{
ListWheelScrollView
(
overAndUnderCenterOpacity:
-
1
,
itemExtent:
20.0
,
children:
<
Widget
>[
Container
()],
);
},
throwsAssertionError
,
);
expect
(
()
{
ListWheelScrollView
(
overAndUnderCenterOpacity:
2
,
itemExtent:
20.0
,
children:
<
Widget
>[
Container
()],
);
},
throwsAssertionError
,
);
expect
(
()
{
ListWheelScrollView
(
overAndUnderCenterOpacity:
1
,
itemExtent:
20.0
,
children:
<
Widget
>[
Container
()],
);
},
isNot
(
throwsAssertionError
),
);
expect
(
()
{
ListWheelScrollView
(
overAndUnderCenterOpacity:
0
,
itemExtent:
20.0
,
children:
<
Widget
>[
Container
()],
);
},
isNot
(
throwsAssertionError
),
);
});
});
});
group
(
'infinite scrolling'
,
()
{
group
(
'infinite scrolling'
,
()
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment