// Copyright 2015 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. import 'package:flutter/widgets.dart'; import 'colors.dart'; import 'constants.dart'; import 'theme.dart'; import 'theme_data.dart'; // Examples can assume: // String userAvatarUrl; /// A circle that represents a user. /// /// Typically used with a user's profile image, or, in the absence of /// such an image, the user's initials. A given user's initials should /// always be paired with the same background color, for consistency. /// /// ## Sample code /// /// If the avatar is to have an image, the image should be specified in the /// [backgroundImage] property: /// /// ```dart /// new CircleAvatar( /// backgroundImage: new NetworkImage(userAvatarUrl), /// ) /// ``` /// /// The image will be cropped to have a circle shape. /// /// If the avatar is to just have the user's initials, they are typically /// provided using a [Text] widget as the [child] and a [backgroundColor]: /// /// ```dart /// new CircleAvatar( /// backgroundColor: Colors.brown.shade800, /// child: new Text('AH'), /// ) /// ``` /// /// See also: /// /// * [Chip], for representing users or concepts in long form. /// * [ListTile], which can combine an icon (such as a [CircleAvatar]) with some /// text for a fixed height list entry. /// * <https://material.google.com/components/chips.html#chips-contact-chips> class CircleAvatar extends StatelessWidget { /// Creates a circle that represents a user. const CircleAvatar({ Key key, this.child, this.backgroundColor, this.backgroundImage, this.foregroundColor, this.radius: 20.0, }) : super(key: key); /// The widget below this widget in the tree. /// /// Typically a [Text] widget. If the [CircleAvatar] is to have an image, use /// [backgroundImage] instead. final Widget child; /// 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. /// /// If the [CircleAvatar] is to have the user's initials, use [child] instead. final ImageProvider backgroundImage; /// The size of the avatar. Changing the radius will cause the /// avatar to animate to the new size. /// /// Defaults to 20 logical pixels. final double radius; @override Widget build(BuildContext context) { assert(debugCheckHasMediaQuery(context)); final ThemeData theme = Theme.of(context); TextStyle textStyle = theme.primaryTextTheme.title; if (foregroundColor != null) { textStyle = textStyle.copyWith(color: foregroundColor); } else if (backgroundColor != null) { switch (ThemeData.estimateBrightnessForColor(backgroundColor)) { case Brightness.dark: textStyle = textStyle.copyWith(color: Colors.white); break; case Brightness.light: textStyle = textStyle.copyWith(color: Colors.black); break; } } return new AnimatedContainer( width: radius * 2.0, height: radius * 2.0, duration: kThemeChangeDuration, decoration: new BoxDecoration( color: backgroundColor ?? theme.primaryColor, image: backgroundImage != null ? new DecorationImage( image: backgroundImage ) : null, shape: BoxShape.circle, ), child: child != null ? new Center( child: new MediaQuery( // Need to reset the textScaleFactor here so that the // text doesn't escape the avatar when the textScaleFactor is large. data: MediaQuery.of(context).copyWith(textScaleFactor: 1.0), child: new DefaultTextStyle( style: textStyle.copyWith(color: foregroundColor), child: child, ), ) ) : null, ); } }