From 2b16202ea24c268440ce1230ce41a4cd206ae434 Mon Sep 17 00:00:00 2001 From: Josh Burton Date: Thu, 13 Feb 2020 10:23:02 +1300 Subject: [PATCH] Adds shadowColor property to the Card widget (#47273) --- packages/flutter/lib/src/material/card.dart | 9 +++++ .../flutter/lib/src/material/card_theme.dart | 12 +++++++ packages/flutter/test/material/card_test.dart | 35 ++++++++++++++++++- .../test/material/card_theme_test.dart | 2 ++ 4 files changed, 57 insertions(+), 1 deletion(-) diff --git a/packages/flutter/lib/src/material/card.dart b/packages/flutter/lib/src/material/card.dart index 0a8e285690..c971933443 100644 --- a/packages/flutter/lib/src/material/card.dart +++ b/packages/flutter/lib/src/material/card.dart @@ -5,6 +5,7 @@ import 'package:flutter/widgets.dart'; import 'card_theme.dart'; +import 'colors.dart'; import 'material.dart'; import 'theme.dart'; @@ -101,6 +102,7 @@ class Card extends StatelessWidget { const Card({ Key key, this.color, + this.shadowColor, this.elevation, this.shape, this.borderOnForeground = true, @@ -120,6 +122,12 @@ class Card extends StatelessWidget { /// if that's null then [ThemeData.cardColor] is used. final Color color; + /// The color to paint the shadow below the card. + /// + /// If null then the ambient [CardTheme]'s shadowColor is used. + /// If that's null too, then the default is fully opaque black. + final Color shadowColor; + /// The z-coordinate at which to place this card. This controls the size of /// the shadow below the card. /// @@ -189,6 +197,7 @@ class Card extends StatelessWidget { margin: margin ?? cardTheme.margin ?? const EdgeInsets.all(4.0), child: Material( type: MaterialType.card, + shadowColor: shadowColor ?? cardTheme.shadowColor ?? Colors.black, color: color ?? cardTheme.color ?? Theme.of(context).cardColor, elevation: elevation ?? cardTheme.elevation ?? _defaultElevation, shape: shape ?? cardTheme.shape ?? const RoundedRectangleBorder( diff --git a/packages/flutter/lib/src/material/card_theme.dart b/packages/flutter/lib/src/material/card_theme.dart index 6f05f3f92b..91e8174508 100644 --- a/packages/flutter/lib/src/material/card_theme.dart +++ b/packages/flutter/lib/src/material/card_theme.dart @@ -34,6 +34,7 @@ class CardTheme extends Diagnosticable { const CardTheme({ this.clipBehavior, this.color, + this.shadowColor, this.elevation, this.margin, this.shape, @@ -49,6 +50,11 @@ class CardTheme extends Diagnosticable { /// If null, [Card] uses [ThemeData.cardColor]. final Color color; + /// Default value for [Card.shadowColor]. + /// + /// If null, [Card] defaults to fully opaque black. + final Color shadowColor; + /// Default value for [Card.elevation]. /// /// If null, [Card] uses a default of 1.0. @@ -71,6 +77,7 @@ class CardTheme extends Diagnosticable { CardTheme copyWith({ Clip clipBehavior, Color color, + Color shadowColor, double elevation, EdgeInsetsGeometry margin, ShapeBorder shape, @@ -78,6 +85,7 @@ class CardTheme extends Diagnosticable { return CardTheme( clipBehavior: clipBehavior ?? this.clipBehavior, color: color ?? this.color, + shadowColor: shadowColor ?? this.shadowColor, elevation: elevation ?? this.elevation, margin: margin ?? this.margin, shape: shape ?? this.shape, @@ -99,6 +107,7 @@ class CardTheme extends Diagnosticable { return CardTheme( clipBehavior: t < 0.5 ? a?.clipBehavior : b?.clipBehavior, color: Color.lerp(a?.color, b?.color, t), + shadowColor: Color.lerp(a?.shadowColor, b?.shadowColor, t), elevation: lerpDouble(a?.elevation, b?.elevation, t), margin: EdgeInsetsGeometry.lerp(a?.margin, b?.margin, t), shape: ShapeBorder.lerp(a?.shape, b?.shape, t), @@ -110,6 +119,7 @@ class CardTheme extends Diagnosticable { return hashValues( clipBehavior, color, + shadowColor, elevation, margin, shape, @@ -125,6 +135,7 @@ class CardTheme extends Diagnosticable { return other is CardTheme && other.clipBehavior == clipBehavior && other.color == color + && other.shadowColor == shadowColor && other.elevation == elevation && other.margin == margin && other.shape == shape; @@ -135,6 +146,7 @@ class CardTheme extends Diagnosticable { super.debugFillProperties(properties); properties.add(DiagnosticsProperty('clipBehavior', clipBehavior, defaultValue: null)); properties.add(ColorProperty('color', color, defaultValue: null)); + properties.add(ColorProperty('shadowColor', shadowColor, defaultValue: null)); properties.add(DiagnosticsProperty('elevation', elevation, defaultValue: null)); properties.add(DiagnosticsProperty('margin', margin, defaultValue: null)); properties.add(DiagnosticsProperty('shape', shape, defaultValue: null)); diff --git a/packages/flutter/test/material/card_test.dart b/packages/flutter/test/material/card_test.dart index ad286c57b7..e583c3e250 100644 --- a/packages/flutter/test/material/card_test.dart +++ b/packages/flutter/test/material/card_test.dart @@ -188,4 +188,37 @@ void main() { })); expect(tester.widget(find.byType(Material)).clipBehavior, Clip.antiAliasWithSaveLayer); }); -} + + testWidgets('Card shadowColor', (WidgetTester tester) async { + Material _getCardMaterial(WidgetTester tester) { + return tester.widget( + find.descendant( + of: find.byType(Card), + matching: find.byType(Material), + ), + ); + } + + Card _getCard(WidgetTester tester) { + return tester.widget( + find.byType(Card) + ); + } + + await tester.pumpWidget( + const Card(), + ); + + expect(_getCard(tester).shadowColor, null); + expect(_getCardMaterial(tester).shadowColor, const Color(0xFF000000)); + + await tester.pumpWidget( + const Card( + shadowColor: Colors.red, + ), + ); + + expect(_getCardMaterial(tester).shadowColor, _getCard(tester).shadowColor); + expect(_getCardMaterial(tester).shadowColor, Colors.red); + }); +} \ No newline at end of file diff --git a/packages/flutter/test/material/card_theme_test.dart b/packages/flutter/test/material/card_theme_test.dart index 2509218040..07226b6b13 100644 --- a/packages/flutter/test/material/card_theme_test.dart +++ b/packages/flutter/test/material/card_theme_test.dart @@ -46,6 +46,7 @@ void main() { expect(material.clipBehavior, cardTheme.clipBehavior); expect(material.color, cardTheme.color); + expect(material.shadowColor, cardTheme.shadowColor); expect(material.elevation, cardTheme.elevation); expect(container.margin, cardTheme.margin); expect(material.shape, cardTheme.shape); @@ -146,6 +147,7 @@ CardTheme _cardTheme() { return const CardTheme( clipBehavior: Clip.antiAlias, color: Colors.green, + shadowColor: Colors.red, elevation: 6.0, margin: EdgeInsets.all(7.0), shape: RoundedRectangleBorder(