Update CircleAvatar
to support Material 3 (#114812)
This commit is contained in:
parent
92f10ed712
commit
d3dcd7d532
@ -84,7 +84,8 @@ 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 [backgroundColor] is not specified, the theme's
|
||||
/// If a [backgroundColor] is not specified and [ThemeData.useMaterial3] is true,
|
||||
/// [ColorScheme.primaryContainer] will be used, otherwise the theme's
|
||||
/// [ThemeData.primaryColorLight] is used with dark foreground colors, and
|
||||
/// [ThemeData.primaryColorDark] with light foreground colors.
|
||||
final Color? backgroundColor;
|
||||
@ -94,7 +95,9 @@ class CircleAvatar extends StatelessWidget {
|
||||
/// Defaults to the primary text theme color if no [backgroundColor] is
|
||||
/// specified.
|
||||
///
|
||||
/// Defaults to [ThemeData.primaryColorLight] for dark background colors, and
|
||||
/// If a [foregroundColor] is not specified and [ThemeData.useMaterial3] is true,
|
||||
/// [ColorScheme.onPrimaryContainer] will be used, otherwise the theme's
|
||||
/// [ThemeData.primaryColorLight] for dark background colors, and
|
||||
/// [ThemeData.primaryColorDark] for light background colors.
|
||||
final Color? foregroundColor;
|
||||
|
||||
@ -192,8 +195,14 @@ class CircleAvatar extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
assert(debugCheckHasMediaQuery(context));
|
||||
final ThemeData theme = Theme.of(context);
|
||||
TextStyle textStyle = theme.primaryTextTheme.titleMedium!.copyWith(color: foregroundColor);
|
||||
Color? effectiveBackgroundColor = backgroundColor;
|
||||
final Color? effectiveForegroundColor = foregroundColor
|
||||
?? (theme.useMaterial3 ? theme.colorScheme.onPrimaryContainer : null);
|
||||
final TextStyle effectiveTextStyle = theme.useMaterial3
|
||||
? theme.textTheme.titleMedium!
|
||||
: theme.primaryTextTheme.titleMedium!;
|
||||
TextStyle textStyle = effectiveTextStyle.copyWith(color: effectiveForegroundColor);
|
||||
Color? effectiveBackgroundColor = backgroundColor
|
||||
?? (theme.useMaterial3 ? theme.colorScheme.primaryContainer : null);
|
||||
if (effectiveBackgroundColor == null) {
|
||||
switch (ThemeData.estimateBrightnessForColor(textStyle.color!)) {
|
||||
case Brightness.dark:
|
||||
@ -203,7 +212,7 @@ class CircleAvatar extends StatelessWidget {
|
||||
effectiveBackgroundColor = theme.primaryColorDark;
|
||||
break;
|
||||
}
|
||||
} else if (foregroundColor == null) {
|
||||
} else if (effectiveForegroundColor == null) {
|
||||
switch (ThemeData.estimateBrightnessForColor(backgroundColor!)) {
|
||||
case Brightness.dark:
|
||||
textStyle = textStyle.copyWith(color: theme.primaryColorLight);
|
||||
|
@ -144,11 +144,8 @@ void main() {
|
||||
expect(paragraph.text.style!.color, equals(foregroundColor));
|
||||
});
|
||||
|
||||
testWidgets('CircleAvatar with light theme', (WidgetTester tester) async {
|
||||
final ThemeData theme = ThemeData(
|
||||
primaryColor: Colors.grey.shade100,
|
||||
primaryColorBrightness: Brightness.light,
|
||||
);
|
||||
testWidgets('CircleAvatar default colors', (WidgetTester tester) async {
|
||||
final ThemeData theme = ThemeData(useMaterial3: true);
|
||||
await tester.pumpWidget(
|
||||
wrap(
|
||||
child: Theme(
|
||||
@ -163,35 +160,10 @@ void main() {
|
||||
final RenderConstrainedBox box = tester.renderObject(find.byType(CircleAvatar));
|
||||
final RenderDecoratedBox child = box.child! as RenderDecoratedBox;
|
||||
final BoxDecoration decoration = child.decoration as BoxDecoration;
|
||||
expect(decoration.color, equals(theme.primaryColorLight));
|
||||
expect(decoration.color, equals(theme.colorScheme.primaryContainer));
|
||||
|
||||
final RenderParagraph paragraph = tester.renderObject(find.text('Z'));
|
||||
expect(paragraph.text.style!.color, equals(theme.primaryTextTheme.titleLarge!.color));
|
||||
});
|
||||
|
||||
testWidgets('CircleAvatar with dark theme', (WidgetTester tester) async {
|
||||
final ThemeData theme = ThemeData(
|
||||
primaryColor: Colors.grey.shade800,
|
||||
primaryColorBrightness: Brightness.dark,
|
||||
);
|
||||
await tester.pumpWidget(
|
||||
wrap(
|
||||
child: Theme(
|
||||
data: theme,
|
||||
child: const CircleAvatar(
|
||||
child: Text('Z'),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
final RenderConstrainedBox box = tester.renderObject(find.byType(CircleAvatar));
|
||||
final RenderDecoratedBox child = box.child! as RenderDecoratedBox;
|
||||
final BoxDecoration decoration = child.decoration as BoxDecoration;
|
||||
expect(decoration.color, equals(theme.primaryColorDark));
|
||||
|
||||
final RenderParagraph paragraph = tester.renderObject(find.text('Z'));
|
||||
expect(paragraph.text.style!.color, equals(theme.primaryTextTheme.titleLarge!.color));
|
||||
expect(paragraph.text.style!.color, equals(theme.colorScheme.onPrimaryContainer));
|
||||
});
|
||||
|
||||
testWidgets('CircleAvatar text does not expand with textScaleFactor', (WidgetTester tester) async {
|
||||
@ -306,6 +278,61 @@ void main() {
|
||||
final RenderParagraph paragraph = tester.renderObject(find.text('Z'));
|
||||
expect(paragraph.text.style!.color, equals(ThemeData.fallback().primaryColorLight));
|
||||
});
|
||||
|
||||
group('Material 2', () {
|
||||
// Tests that are only relevant for Material 2. Once ThemeData.useMaterial3
|
||||
// is turned on by default, these tests can be removed.
|
||||
|
||||
testWidgets('CircleAvatar default colors with light theme', (WidgetTester tester) async {
|
||||
final ThemeData theme = ThemeData(
|
||||
primaryColor: Colors.grey.shade100,
|
||||
primaryColorBrightness: Brightness.light,
|
||||
);
|
||||
await tester.pumpWidget(
|
||||
wrap(
|
||||
child: Theme(
|
||||
data: theme,
|
||||
child: const CircleAvatar(
|
||||
child: Text('Z'),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
final RenderConstrainedBox box = tester.renderObject(find.byType(CircleAvatar));
|
||||
final RenderDecoratedBox child = box.child! as RenderDecoratedBox;
|
||||
final BoxDecoration decoration = child.decoration as BoxDecoration;
|
||||
expect(decoration.color, equals(theme.primaryColorLight));
|
||||
|
||||
final RenderParagraph paragraph = tester.renderObject(find.text('Z'));
|
||||
expect(paragraph.text.style!.color, equals(theme.primaryTextTheme.titleLarge!.color));
|
||||
});
|
||||
|
||||
testWidgets('CircleAvatar default colors with dark theme', (WidgetTester tester) async {
|
||||
final ThemeData theme = ThemeData(
|
||||
primaryColor: Colors.grey.shade800,
|
||||
primaryColorBrightness: Brightness.dark,
|
||||
);
|
||||
await tester.pumpWidget(
|
||||
wrap(
|
||||
child: Theme(
|
||||
data: theme,
|
||||
child: const CircleAvatar(
|
||||
child: Text('Z'),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
final RenderConstrainedBox box = tester.renderObject(find.byType(CircleAvatar));
|
||||
final RenderDecoratedBox child = box.child! as RenderDecoratedBox;
|
||||
final BoxDecoration decoration = child.decoration as BoxDecoration;
|
||||
expect(decoration.color, equals(theme.primaryColorDark));
|
||||
|
||||
final RenderParagraph paragraph = tester.renderObject(find.text('Z'));
|
||||
expect(paragraph.text.style!.color, equals(theme.primaryTextTheme.titleLarge!.color));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Widget wrap({ required Widget child }) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user