Added ability to change dropdown colour manually (#52982)

This commit is contained in:
impure 2020-04-02 13:21:04 -04:00 committed by GitHub
parent 54d75a515a
commit 191f86ea05
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 66 additions and 1 deletions

View file

@ -203,12 +203,14 @@ class _DropdownMenu<T> extends StatefulWidget {
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 @@ class _DropdownMenuState<T> extends State<_DropdownMenu<T>> {
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 @@ class _DropdownRoute<T> extends PopupRoute<_DropdownRouteResult<T>> {
@required this.style,
this.barrierLabel,
this.itemHeight,
this.dropdownColor,
}) : assert(style != null),
itemHeights = List<double>.filled(items.length, itemHeight ?? kMinInteractiveDimension);
@ -411,6 +414,7 @@ class _DropdownRoute<T> extends PopupRoute<_DropdownRouteResult<T>> {
final ThemeData theme;
final TextStyle style;
final double itemHeight;
final Color dropdownColor;
final List<double> itemHeights;
ScrollController scrollController;
@ -441,6 +445,7 @@ class _DropdownRoute<T> extends PopupRoute<_DropdownRouteResult<T>> {
elevation: elevation,
theme: theme,
style: style,
dropdownColor: dropdownColor,
);
}
);
@ -526,6 +531,7 @@ class _DropdownRoutePage<T> extends StatelessWidget {
this.elevation = 8,
this.theme,
this.style,
this.dropdownColor,
}) : super(key: key);
final _DropdownRoute<T> route;
@ -537,6 +543,7 @@ class _DropdownRoutePage<T> extends StatelessWidget {
final int elevation;
final ThemeData theme;
final TextStyle style;
final Color dropdownColor;
@override
Widget build(BuildContext context) {
@ -559,6 +566,7 @@ class _DropdownRoutePage<T> extends StatelessWidget {
padding: padding.resolve(textDirection),
buttonRect: buttonRect,
constraints: constraints,
dropdownColor: dropdownColor,
);
if (theme != null)
@ -789,6 +797,10 @@ class DropdownButton<T> extends StatefulWidget {
/// 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 @@ class DropdownButton<T> extends StatefulWidget {
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 @@ class DropdownButton<T> extends StatefulWidget {
/// {@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 @@ class _DropdownButtonState<T> extends State<DropdownButton<T>> with WidgetsBindi
style: _textStyle,
barrierLabel: MaterialLocalizations.of(context).modalBarrierDismissLabel,
itemHeight: widget.itemHeight,
dropdownColor: widget.dropdownColor,
);
Navigator.push(context, _dropdownRoute).then<void>((_DropdownRouteResult<T> newValue) {

View file

@ -53,6 +53,7 @@ Widget buildFrame({
FocusNode focusNode,
bool autofocus = false,
Color focusColor,
Color dropdownColor,
}) {
return TestApp(
textDirection: textDirection,
@ -78,6 +79,7 @@ Widget buildFrame({
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 @@ void verifyPaintedShadow(Finder customPaint, int elevation) {
);
}
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 @@ void main() {
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'];