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
|
/// The color with which to fill the circle. Changing the background
|
||||||
/// color will cause the avatar to animate to the new color.
|
/// 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.primaryColorLight] is used with dark foreground colors, and
|
||||||
/// [ThemeData.primaryColorDark] with light foreground colors.
|
/// [ThemeData.primaryColorDark] with light foreground colors.
|
||||||
final Color? backgroundColor;
|
final Color? backgroundColor;
|
||||||
@ -94,7 +95,9 @@ class CircleAvatar extends StatelessWidget {
|
|||||||
/// Defaults to the primary text theme color if no [backgroundColor] is
|
/// Defaults to the primary text theme color if no [backgroundColor] is
|
||||||
/// specified.
|
/// 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.
|
/// [ThemeData.primaryColorDark] for light background colors.
|
||||||
final Color? foregroundColor;
|
final Color? foregroundColor;
|
||||||
|
|
||||||
@ -192,8 +195,14 @@ class CircleAvatar extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
assert(debugCheckHasMediaQuery(context));
|
assert(debugCheckHasMediaQuery(context));
|
||||||
final ThemeData theme = Theme.of(context);
|
final ThemeData theme = Theme.of(context);
|
||||||
TextStyle textStyle = theme.primaryTextTheme.titleMedium!.copyWith(color: foregroundColor);
|
final Color? effectiveForegroundColor = foregroundColor
|
||||||
Color? effectiveBackgroundColor = backgroundColor;
|
?? (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) {
|
if (effectiveBackgroundColor == null) {
|
||||||
switch (ThemeData.estimateBrightnessForColor(textStyle.color!)) {
|
switch (ThemeData.estimateBrightnessForColor(textStyle.color!)) {
|
||||||
case Brightness.dark:
|
case Brightness.dark:
|
||||||
@ -203,7 +212,7 @@ class CircleAvatar extends StatelessWidget {
|
|||||||
effectiveBackgroundColor = theme.primaryColorDark;
|
effectiveBackgroundColor = theme.primaryColorDark;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else if (foregroundColor == null) {
|
} else if (effectiveForegroundColor == null) {
|
||||||
switch (ThemeData.estimateBrightnessForColor(backgroundColor!)) {
|
switch (ThemeData.estimateBrightnessForColor(backgroundColor!)) {
|
||||||
case Brightness.dark:
|
case Brightness.dark:
|
||||||
textStyle = textStyle.copyWith(color: theme.primaryColorLight);
|
textStyle = textStyle.copyWith(color: theme.primaryColorLight);
|
||||||
|
@ -144,11 +144,8 @@ void main() {
|
|||||||
expect(paragraph.text.style!.color, equals(foregroundColor));
|
expect(paragraph.text.style!.color, equals(foregroundColor));
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('CircleAvatar with light theme', (WidgetTester tester) async {
|
testWidgets('CircleAvatar default colors', (WidgetTester tester) async {
|
||||||
final ThemeData theme = ThemeData(
|
final ThemeData theme = ThemeData(useMaterial3: true);
|
||||||
primaryColor: Colors.grey.shade100,
|
|
||||||
primaryColorBrightness: Brightness.light,
|
|
||||||
);
|
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
wrap(
|
wrap(
|
||||||
child: Theme(
|
child: Theme(
|
||||||
@ -163,35 +160,10 @@ void main() {
|
|||||||
final RenderConstrainedBox box = tester.renderObject(find.byType(CircleAvatar));
|
final RenderConstrainedBox box = tester.renderObject(find.byType(CircleAvatar));
|
||||||
final RenderDecoratedBox child = box.child! as RenderDecoratedBox;
|
final RenderDecoratedBox child = box.child! as RenderDecoratedBox;
|
||||||
final BoxDecoration decoration = child.decoration as BoxDecoration;
|
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'));
|
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 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));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('CircleAvatar text does not expand with textScaleFactor', (WidgetTester tester) async {
|
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'));
|
final RenderParagraph paragraph = tester.renderObject(find.text('Z'));
|
||||||
expect(paragraph.text.style!.color, equals(ThemeData.fallback().primaryColorLight));
|
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 }) {
|
Widget wrap({ required Widget child }) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user