Allows for the CupertinoPicker to have a non white background color (#24085)
* fixes wheel gradient and adds test
This commit is contained in:
parent
26a6fd92d8
commit
6a8c393f4c
@ -39,7 +39,8 @@ class CupertinoPicker extends StatefulWidget {
|
|||||||
///
|
///
|
||||||
/// The [backgroundColor] defaults to light gray. It can be set to null to
|
/// The [backgroundColor] defaults to light gray. It can be set to null to
|
||||||
/// disable the background painting entirely; this is mildly more efficient
|
/// disable the background painting entirely; this is mildly more efficient
|
||||||
/// than using [Colors.transparent].
|
/// than using [Colors.transparent]. Also, if it has transparency, no gradient
|
||||||
|
/// effect will be rendered.
|
||||||
///
|
///
|
||||||
/// The [looping] argument decides whether the child list loops and can be
|
/// The [looping] argument decides whether the child list loops and can be
|
||||||
/// scrolled infinitely. If set to true, scrolling past the end of the list
|
/// scrolled infinitely. If set to true, scrolling past the end of the list
|
||||||
@ -121,6 +122,9 @@ class CupertinoPicker extends StatefulWidget {
|
|||||||
///
|
///
|
||||||
/// This can be set to null to disable the background painting entirely; this
|
/// This can be set to null to disable the background painting entirely; this
|
||||||
/// is mildly more efficient than using [Colors.transparent].
|
/// is mildly more efficient than using [Colors.transparent].
|
||||||
|
///
|
||||||
|
/// Any alpha value less 255 (fully opaque) will cause the removal of the
|
||||||
|
/// wheel list edge fade gradient from rendering of the widget.
|
||||||
final Color backgroundColor;
|
final Color backgroundColor;
|
||||||
|
|
||||||
/// {@macro flutter.rendering.wheelList.offAxisFraction}
|
/// {@macro flutter.rendering.wheelList.offAxisFraction}
|
||||||
@ -202,24 +206,32 @@ class _CupertinoPickerState extends State<CupertinoPicker> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Makes the fade to white edge gradients.
|
/// Makes the fade to [CupertinoPicker.backgroundColor] edge gradients.
|
||||||
Widget _buildGradientScreen() {
|
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;
|
||||||
return Positioned.fill(
|
return Positioned.fill(
|
||||||
child: IgnorePointer(
|
child: IgnorePointer(
|
||||||
child: Container(
|
child: Container(
|
||||||
decoration: const BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
gradient: LinearGradient(
|
gradient: LinearGradient(
|
||||||
colors: <Color>[
|
colors: <Color>[
|
||||||
Color(0xFFFFFFFF),
|
widgetBackgroundColor,
|
||||||
Color(0xF2FFFFFF),
|
widgetBackgroundColor.withAlpha(0xF2),
|
||||||
Color(0xDDFFFFFF),
|
widgetBackgroundColor.withAlpha(0xDD),
|
||||||
Color(0x00FFFFFF),
|
widgetBackgroundColor.withAlpha(0),
|
||||||
Color(0x00FFFFFF),
|
widgetBackgroundColor.withAlpha(0),
|
||||||
Color(0xDDFFFFFF),
|
widgetBackgroundColor.withAlpha(0xDD),
|
||||||
Color(0xF2FFFFFF),
|
widgetBackgroundColor.withAlpha(0xF2),
|
||||||
Color(0xFFFFFFFF),
|
widgetBackgroundColor,
|
||||||
],
|
],
|
||||||
stops: <double>[
|
stops: const <double>[
|
||||||
0.0, 0.05, 0.09, 0.22, 0.78, 0.91, 0.95, 1.0,
|
0.0, 0.05, 0.09, 0.22, 0.78, 0.91, 0.95, 1.0,
|
||||||
],
|
],
|
||||||
begin: Alignment.topCenter,
|
begin: Alignment.topCenter,
|
||||||
@ -267,6 +279,34 @@ class _CupertinoPickerState extends State<CupertinoPicker> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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(
|
||||||
|
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 = Stack(
|
Widget result = Stack(
|
||||||
@ -292,13 +332,17 @@ class _CupertinoPickerState extends State<CupertinoPicker> {
|
|||||||
_buildMagnifierScreen(),
|
_buildMagnifierScreen(),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
if (widget.backgroundColor != null) {
|
// Adds the appropriate opacity under the magnifier if the background
|
||||||
result = DecoratedBox(
|
// color is transparent.
|
||||||
decoration: BoxDecoration(
|
if (widget.backgroundColor != null && widget.backgroundColor.alpha < 255) {
|
||||||
color: widget.backgroundColor,
|
result = Stack(
|
||||||
),
|
children: <Widget> [
|
||||||
child: result,
|
_buildUnderMagnifierScreen(),
|
||||||
|
_addBackgroundToChild(result),
|
||||||
|
]
|
||||||
);
|
);
|
||||||
|
} else {
|
||||||
|
result = _addBackgroundToChild(result);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -56,6 +56,84 @@ void main() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
group('gradient', () {
|
||||||
|
testWidgets('gradient displays correctly with background color', (WidgetTester tester) async {
|
||||||
|
const Color backgroundColor = Color.fromRGBO(255, 0, 0, 1.0);
|
||||||
|
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 Container container = tester.firstWidget(find.byType(Container));
|
||||||
|
final BoxDecoration boxDecoration = container.decoration;
|
||||||
|
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 {
|
||||||
|
const Color backgroundColor = Color.fromRGBO(255, 0, 0, 0.5);
|
||||||
|
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;
|
||||||
|
expect(boxDecoration.gradient, isNull);
|
||||||
|
expect(boxDecoration.color, isNotNull);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
group('scroll', () {
|
group('scroll', () {
|
||||||
testWidgets(
|
testWidgets(
|
||||||
'scrolling calls onSelectedItemChanged and triggers haptic feedback',
|
'scrolling calls onSelectedItemChanged and triggers haptic feedback',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user