Added ability to change dropdown colour manually (#52982)
diff --git a/packages/flutter/lib/src/material/dropdown.dart b/packages/flutter/lib/src/material/dropdown.dart
index f4eb342..fe22689 100644
--- a/packages/flutter/lib/src/material/dropdown.dart
+++ b/packages/flutter/lib/src/material/dropdown.dart
@@ -203,12 +203,14 @@
this.route,
this.buttonRect,
this.constraints,
+ this.dropdownColor,
}) : super(key: key);
final _DropdownRoute<T> route;
final EdgeInsets padding;
final Rect buttonRect;
final BoxConstraints constraints;
+ final Color dropdownColor;
@override
_DropdownMenuState<T> createState() => _DropdownMenuState<T>();
@@ -265,7 +267,7 @@
opacity: _fadeOpacity,
child: CustomPaint(
painter: _DropdownMenuPainter(
- color: Theme.of(context).canvasColor,
+ color: widget.dropdownColor ?? Theme.of(context).canvasColor,
elevation: route.elevation,
selectedIndex: route.selectedIndex,
resize: _resize,
@@ -400,6 +402,7 @@
@required this.style,
this.barrierLabel,
this.itemHeight,
+ this.dropdownColor,
}) : assert(style != null),
itemHeights = List<double>.filled(items.length, itemHeight ?? kMinInteractiveDimension);
@@ -411,6 +414,7 @@
final ThemeData theme;
final TextStyle style;
final double itemHeight;
+ final Color dropdownColor;
final List<double> itemHeights;
ScrollController scrollController;
@@ -441,6 +445,7 @@
elevation: elevation,
theme: theme,
style: style,
+ dropdownColor: dropdownColor,
);
}
);
@@ -526,6 +531,7 @@
this.elevation = 8,
this.theme,
this.style,
+ this.dropdownColor,
}) : super(key: key);
final _DropdownRoute<T> route;
@@ -537,6 +543,7 @@
final int elevation;
final ThemeData theme;
final TextStyle style;
+ final Color dropdownColor;
@override
Widget build(BuildContext context) {
@@ -559,6 +566,7 @@
padding: padding.resolve(textDirection),
buttonRect: buttonRect,
constraints: constraints,
+ dropdownColor: dropdownColor,
);
if (theme != null)
@@ -789,6 +797,10 @@
/// The [elevation] and [iconSize] arguments must not be null (they both have
/// defaults, so do not need to be specified). The boolean [isDense] and
/// [isExpanded] arguments must not be null.
+ ///
+ /// The [dropdownColor] argument specifies the background color of the
+ /// dropdown when it is open. If it is null, the current theme's
+ /// [ThemeData.canvasColor] will be used instead.
DropdownButton({
Key key,
@required this.items,
@@ -811,6 +823,7 @@
this.focusColor,
this.focusNode,
this.autofocus = false,
+ this.dropdownColor,
}) : assert(items == null || items.isEmpty || value == null ||
items.where((DropdownMenuItem<T> item) {
return item.value == value;
@@ -1049,6 +1062,12 @@
/// {@macro flutter.widgets.Focus.autofocus}
final bool autofocus;
+ /// The background color of the dropdown.
+ ///
+ /// If it is not provided, the theme's [ThemeData.canvasColor] will be used
+ /// instead.
+ final Color dropdownColor;
+
@override
_DropdownButtonState<T> createState() => _DropdownButtonState<T>();
}
@@ -1189,6 +1208,7 @@
style: _textStyle,
barrierLabel: MaterialLocalizations.of(context).modalBarrierDismissLabel,
itemHeight: widget.itemHeight,
+ dropdownColor: widget.dropdownColor,
);
Navigator.push(context, _dropdownRoute).then<void>((_DropdownRouteResult<T> newValue) {
diff --git a/packages/flutter/test/material/dropdown_test.dart b/packages/flutter/test/material/dropdown_test.dart
index 6a78caf..57ff78d 100644
--- a/packages/flutter/test/material/dropdown_test.dart
+++ b/packages/flutter/test/material/dropdown_test.dart
@@ -53,6 +53,7 @@
FocusNode focusNode,
bool autofocus = false,
Color focusColor,
+ Color dropdownColor,
}) {
return TestApp(
textDirection: textDirection,
@@ -78,6 +79,7 @@
focusNode: focusNode,
autofocus: autofocus,
focusColor: focusColor,
+ dropdownColor: dropdownColor,
items: items == null ? null : items.map<DropdownMenuItem<String>>((String item) {
return DropdownMenuItem<String>(
key: ValueKey<String>(item),
@@ -174,6 +176,41 @@
);
}
+Future<void> checkDropdownColor(WidgetTester tester, {Color color}) async {
+ const String text = 'foo';
+ await tester.pumpWidget(
+ MaterialApp(
+ home: Material(
+ child: DropdownButton<String>(
+ dropdownColor: color,
+ value: text,
+ items: const <DropdownMenuItem<String>>[
+ DropdownMenuItem<String>(
+ value: text,
+ child: Text(text),
+ ),
+ ],
+ onChanged: (_) { },
+ ),
+ ),
+ ),
+ );
+ await tester.tap(find.text(text));
+ await tester.pump();
+
+ expect(
+ find.ancestor(
+ of: find.text(text).last,
+ matching: find.byType(CustomPaint)).at(2),
+ paints
+ ..save()
+ ..rrect()
+ ..rrect()
+ ..rrect()
+ ..rrect(color: color ?? Colors.grey[50], hasMaskFilter: false)
+ );
+}
+
bool sameGeometry(RenderBox box1, RenderBox box2) {
expect(box1.localToGlobal(Offset.zero), equals(box2.localToGlobal(Offset.zero)));
expect(box1.size.height, equals(box2.size.height));
@@ -1774,6 +1811,14 @@
expect(find.text('Two as an Arabic numeral: 2'), findsOneWidget);
});
+ testWidgets('DropdownButton uses default color when expanded', (WidgetTester tester) async {
+ await checkDropdownColor(tester);
+ });
+
+ testWidgets('DropdownButton uses dropdownColor when expanded when given', (WidgetTester tester) async {
+ await checkDropdownColor(tester, color: const Color.fromRGBO(120, 220, 70, 0.8));
+ });
+
testWidgets('DropdownButton hint displays properly when selectedItemBuilder is defined', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/42340
final List<String> items = <String>['1', '2', '3'];