diff --git a/packages/flutter/lib/src/material/circle_avatar.dart b/packages/flutter/lib/src/material/circle_avatar.dart index b93e0eee03..dfd1a805ed 100644 --- a/packages/flutter/lib/src/material/circle_avatar.dart +++ b/packages/flutter/lib/src/material/circle_avatar.dart @@ -7,6 +7,7 @@ import 'package:flutter/widgets.dart'; import 'constants.dart'; import 'theme.dart'; +import 'typography.dart'; /// A circle that represents a user. /// @@ -48,7 +49,8 @@ class CircleAvatar extends StatelessWidget { this.child, this.backgroundColor, this.backgroundImage, - this.radius: 20.0 + this.foregroundColor, + this.radius: 20.0, }) : super(key: key); /// The widget below this widget in the tree. @@ -59,8 +61,16 @@ class CircleAvatar extends StatelessWidget { /// The color with which to fill the circle. Changing the background /// color will cause the avatar to animate to the new color. + /// + /// If a background color is not specified, the theme's primary color is used. final Color backgroundColor; + /// The default text color for text in the circle. + /// + /// Falls back to white if a background color is specified, or the primary + /// text theme color otherwise. + final Color foregroundColor; + /// The background image of the circle. Changing the background /// image will cause the avatar to animate to the new image. /// @@ -76,13 +86,15 @@ class CircleAvatar extends StatelessWidget { @override Widget build(BuildContext context) { final ThemeData theme = Theme.of(context); - final Color color = backgroundColor ?? theme.primaryColor; + final TextStyle textStyle = backgroundColor != null ? + new Typography(platform: theme.platform).white.title : + theme.primaryTextTheme.title; return new AnimatedContainer( width: radius * 2.0, height: radius * 2.0, duration: kThemeChangeDuration, decoration: new BoxDecoration( - backgroundColor: color, + backgroundColor: backgroundColor ?? theme.primaryColor, backgroundImage: backgroundImage != null ? new BackgroundImage( image: backgroundImage ) : null, @@ -90,7 +102,7 @@ class CircleAvatar extends StatelessWidget { ), child: child != null ? new Center( child: new DefaultTextStyle( - style: theme.primaryTextTheme.title, + style: textStyle.copyWith(color: foregroundColor), child: child, ) ) : null, diff --git a/packages/flutter/test/material/circle_avatar_test.dart b/packages/flutter/test/material/circle_avatar_test.dart index 7b3ffe4486..b73caff5cd 100644 --- a/packages/flutter/test/material/circle_avatar_test.dart +++ b/packages/flutter/test/material/circle_avatar_test.dart @@ -3,24 +3,79 @@ // found in the LICENSE file. import 'package:flutter/material.dart'; +import 'package:flutter/rendering.dart'; import 'package:flutter_test/flutter_test.dart'; void main() { - testWidgets('CircleAvatar test', (WidgetTester tester) async { + testWidgets('CircleAvatar with background color', (WidgetTester tester) async { + final Color backgroundColor = Colors.blue.shade400; await tester.pumpWidget( new Center( child: new CircleAvatar( - backgroundColor: Colors.blue[400], + backgroundColor: backgroundColor, radius: 50.0, - child: new Text('Z') - ) - ) + child: new Text('Z'), + ), + ), ); - final RenderBox box = tester.renderObject(find.byType(CircleAvatar)); + final RenderConstrainedBox box = tester.renderObject(find.byType(CircleAvatar)); expect(box.size.width, equals(100.0)); expect(box.size.height, equals(100.0)); + final RenderDecoratedBox child = box.child; + final BoxDecoration decoration = child.decoration; + expect(decoration.backgroundColor, equals(backgroundColor)); - expect(find.text('Z'), findsOneWidget); + final RenderParagraph paragraph = tester.renderObject(find.text('Z')); + expect(paragraph.text.style.color, equals(Colors.white)); + }); + + testWidgets('CircleAvatar with foreground color', (WidgetTester tester) async { + final Color foregroundColor = Colors.red.shade100; + await tester.pumpWidget( + new Center( + child: new CircleAvatar( + foregroundColor: foregroundColor, + child: new Text('Z'), + ), + ), + ); + + final ThemeData fallback = new ThemeData.fallback(); + + final RenderConstrainedBox box = tester.renderObject(find.byType(CircleAvatar)); + expect(box.size.width, equals(40.0)); + expect(box.size.height, equals(40.0)); + final RenderDecoratedBox child = box.child; + final BoxDecoration decoration = child.decoration; + expect(decoration.backgroundColor, equals(fallback.primaryColor)); + + final RenderParagraph paragraph = tester.renderObject(find.text('Z')); + expect(paragraph.text.style.color, equals(foregroundColor)); + }); + + testWidgets('CircleAvatar with theme', (WidgetTester tester) async { + final ThemeData theme = new ThemeData( + primaryColor: Colors.grey.shade100, + primaryColorBrightness: Brightness.light, + ); + await tester.pumpWidget( + new Theme( + data: theme, + child: new Center( + child: new CircleAvatar( + child: new Text('Z'), + ), + ), + ), + ); + + final RenderConstrainedBox box = tester.renderObject(find.byType(CircleAvatar)); + final RenderDecoratedBox child = box.child; + final BoxDecoration decoration = child.decoration; + expect(decoration.backgroundColor, equals(theme.primaryColor)); + + final RenderParagraph paragraph = tester.renderObject(find.text('Z')); + expect(paragraph.text.style.color, equals(theme.primaryTextTheme.title.color)); }); }