mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Update AppBar and AppBarTheme tests for M2/M3 (#130790)
Updated unit tests for `AppBar` and `AppBarTheme` to have M2 and M3 versions. More info in https://github.com/flutter/flutter/issues/127064
This commit is contained in:
parent
86385dce68
commit
b460d49199
@ -559,10 +559,11 @@ void main() {
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('AppBar drawer icon has default color', (WidgetTester tester) async {
|
||||
final ThemeData themeData = ThemeData.from(colorScheme: const ColorScheme.light());
|
||||
final bool useMaterial3 = themeData.useMaterial3;
|
||||
|
||||
testWidgets('Material2 - AppBar drawer icon has default color', (WidgetTester tester) async {
|
||||
final ThemeData themeData = ThemeData.from(
|
||||
colorScheme: const ColorScheme.light(),
|
||||
useMaterial3: false,
|
||||
);
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
theme: themeData,
|
||||
@ -575,10 +576,27 @@ void main() {
|
||||
),
|
||||
);
|
||||
|
||||
Color? iconColor() => _iconStyle(tester, Icons.menu)?.color;
|
||||
final Color iconColorM2 = themeData.colorScheme.onPrimary;
|
||||
final Color iconColorM3 = themeData.colorScheme.onSurfaceVariant;
|
||||
expect(iconColor(), useMaterial3 ? iconColorM3 : iconColorM2);
|
||||
expect(_iconStyle(tester, Icons.menu)?.color, themeData.colorScheme.onPrimary);
|
||||
});
|
||||
|
||||
testWidgets('Material3 - AppBar drawer icon has default color', (WidgetTester tester) async {
|
||||
final ThemeData themeData = ThemeData.from(
|
||||
colorScheme: const ColorScheme.light(),
|
||||
useMaterial3: true,
|
||||
);
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
theme: themeData,
|
||||
home: Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('Howdy!'),
|
||||
),
|
||||
drawer: const Drawer(),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(_iconStyle(tester, Icons.menu)?.color, themeData.colorScheme.onSurfaceVariant);
|
||||
});
|
||||
|
||||
testWidgets('AppBar drawer icon is sized by iconTheme', (WidgetTester tester) async {
|
||||
@ -616,9 +634,7 @@ void main() {
|
||||
),
|
||||
);
|
||||
|
||||
Color? iconColor() => _iconStyle(tester, Icons.menu)?.color;
|
||||
|
||||
expect(iconColor(), color);
|
||||
expect(_iconStyle(tester, Icons.menu)?.color, color);
|
||||
});
|
||||
|
||||
testWidgets('AppBar endDrawer icon has default size', (WidgetTester tester) async {
|
||||
@ -632,6 +648,7 @@ void main() {
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
final double iconSize = const IconThemeData.fallback().size!;
|
||||
expect(
|
||||
tester.getSize(find.byIcon(Icons.menu)),
|
||||
@ -639,10 +656,11 @@ void main() {
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('AppBar endDrawer icon has default color', (WidgetTester tester) async {
|
||||
final ThemeData themeData = ThemeData.from(colorScheme: const ColorScheme.light());
|
||||
final bool useMaterial3 = themeData.useMaterial3;
|
||||
|
||||
testWidgets('Material2 - AppBar endDrawer icon has default color', (WidgetTester tester) async {
|
||||
final ThemeData themeData = ThemeData.from(
|
||||
colorScheme: const ColorScheme.light(),
|
||||
useMaterial3: false,
|
||||
);
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
theme: themeData,
|
||||
@ -655,10 +673,27 @@ void main() {
|
||||
),
|
||||
);
|
||||
|
||||
Color? iconColor() => _iconStyle(tester, Icons.menu)?.color;
|
||||
final Color iconColorM2 = themeData.colorScheme.onPrimary;
|
||||
final Color iconColorM3 = themeData.colorScheme.onSurfaceVariant;
|
||||
expect(iconColor(), useMaterial3 ? iconColorM3 : iconColorM2);
|
||||
expect(_iconStyle(tester, Icons.menu)?.color, themeData.colorScheme.onPrimary);
|
||||
});
|
||||
|
||||
testWidgets('Material3 - AppBar endDrawer icon has default color', (WidgetTester tester) async {
|
||||
final ThemeData themeData = ThemeData.from(
|
||||
colorScheme: const ColorScheme.light(),
|
||||
useMaterial3: true,
|
||||
);
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
theme: themeData,
|
||||
home: Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('Howdy!'),
|
||||
),
|
||||
endDrawer: const Drawer(),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(_iconStyle(tester, Icons.menu)?.color, themeData.colorScheme.onSurfaceVariant);
|
||||
});
|
||||
|
||||
testWidgets('AppBar endDrawer icon is sized by iconTheme', (WidgetTester tester) async {
|
||||
@ -696,14 +731,14 @@ void main() {
|
||||
),
|
||||
);
|
||||
|
||||
Color? iconColor() => _iconStyle(tester, Icons.menu)?.color;
|
||||
|
||||
expect(iconColor(), color);
|
||||
expect(_iconStyle(tester, Icons.menu)?.color, color);
|
||||
});
|
||||
|
||||
testWidgets('leading widget extends to edge and is square', (WidgetTester tester) async {
|
||||
final ThemeData themeData = ThemeData(platform: TargetPlatform.android);
|
||||
final bool material3 = themeData.useMaterial3;
|
||||
testWidgets('Material2 - leading widget extends to edge and is square', (WidgetTester tester) async {
|
||||
final ThemeData themeData = ThemeData(
|
||||
platform: TargetPlatform.android,
|
||||
useMaterial3: false,
|
||||
);
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
theme: themeData,
|
||||
@ -717,10 +752,10 @@ void main() {
|
||||
),
|
||||
);
|
||||
|
||||
// Default IconButton has a size of (48x48) in M3, (56x56) in M2
|
||||
// Default IconButton has a size of (56x56).
|
||||
final Finder hamburger = find.byType(IconButton);
|
||||
expect(tester.getTopLeft(hamburger), material3 ? const Offset(4.0, 4.0) : Offset.zero);
|
||||
expect(tester.getSize(hamburger), material3 ? const Size(48.0, 48.0) : const Size(56.0, 56.0));
|
||||
expect(tester.getTopLeft(hamburger), Offset.zero);
|
||||
expect(tester.getSize(hamburger), const Size(56.0, 56.0));
|
||||
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
@ -734,7 +769,7 @@ void main() {
|
||||
),
|
||||
);
|
||||
|
||||
// Default leading widget has a size of (56x56) for both M2 and M3
|
||||
// Default leading widget has a size of (56x56).
|
||||
final Finder leadingBox = find.byType(Container);
|
||||
expect(tester.getTopLeft(leadingBox), Offset.zero);
|
||||
expect(tester.getSize(leadingBox), const Size(56.0, 56.0));
|
||||
@ -757,9 +792,69 @@ void main() {
|
||||
expect(tester.getSize(leading), const Size(56.0, 56.0));
|
||||
});
|
||||
|
||||
testWidgets('test action is 4dp from edge and 48dp min', (WidgetTester tester) async {
|
||||
final ThemeData theme = ThemeData(platform: TargetPlatform.android);
|
||||
final bool material3 = theme.useMaterial3;
|
||||
testWidgets('Material3 - leading widget extends to edge and is square', (WidgetTester tester) async {
|
||||
final ThemeData themeData = ThemeData(
|
||||
platform: TargetPlatform.android,
|
||||
useMaterial3: true,
|
||||
);
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
theme: themeData,
|
||||
home: Scaffold(
|
||||
appBar: AppBar(
|
||||
leading: IconButton(icon: const Icon(Icons.menu), onPressed: () {}),
|
||||
title: const Text('X'),
|
||||
),
|
||||
drawer: const Column(), // Doesn't really matter. Triggers a hamburger regardless.
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
// Default IconButton has a size of (48x48).
|
||||
final Finder hamburger = find.byType(IconButton);
|
||||
expect(tester.getTopLeft(hamburger), const Offset(4.0, 4.0));
|
||||
expect(tester.getSize(hamburger), const Size(48.0, 48.0));
|
||||
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
theme: themeData,
|
||||
home: Scaffold(
|
||||
appBar: AppBar(
|
||||
leading: Container(),
|
||||
title: const Text('X'),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
// Default leading widget has a size of (56x56).
|
||||
final Finder leadingBox = find.byType(Container);
|
||||
expect(tester.getTopLeft(leadingBox), Offset.zero);
|
||||
expect(tester.getSize(leadingBox), const Size(56.0, 56.0));
|
||||
|
||||
// The custom leading widget should still be 56x56 even if its size is smaller.
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
theme: themeData,
|
||||
home: Scaffold(
|
||||
appBar: AppBar(
|
||||
leading: const SizedBox(height: 36, width: 36,),
|
||||
title: const Text('X'),
|
||||
), // Doesn't really matter. Triggers a hamburger regardless.
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
final Finder leading = find.byType(SizedBox);
|
||||
expect(tester.getTopLeft(leading), Offset.zero);
|
||||
expect(tester.getSize(leading), const Size(56.0, 56.0));
|
||||
});
|
||||
|
||||
testWidgets('Material2 - Action is 4dp from edge and 48dp min', (WidgetTester tester) async {
|
||||
final ThemeData theme = ThemeData(
|
||||
platform: TargetPlatform.android,
|
||||
useMaterial3: false,
|
||||
);
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
theme: theme,
|
||||
@ -792,7 +887,47 @@ void main() {
|
||||
|
||||
final Finder shareButton = find.widgetWithIcon(IconButton, Icons.share);
|
||||
// The 20dp icon is expanded to fill the IconButton's touch target to 48dp.
|
||||
expect(tester.getSize(shareButton), material3 ? const Size(48.0, 48.0) : const Size(48.0, 56.0));
|
||||
expect(tester.getSize(shareButton), const Size(48.0, 56.0));
|
||||
});
|
||||
|
||||
testWidgets('Material3 - Action is 4dp from edge and 48dp min', (WidgetTester tester) async {
|
||||
final ThemeData theme = ThemeData(
|
||||
platform: TargetPlatform.android,
|
||||
useMaterial3: true,
|
||||
);
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
theme: theme,
|
||||
home: Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('X'),
|
||||
actions: const <Widget> [
|
||||
IconButton(
|
||||
icon: Icon(Icons.share),
|
||||
onPressed: null,
|
||||
tooltip: 'Share',
|
||||
iconSize: 20.0,
|
||||
),
|
||||
IconButton(
|
||||
icon: Icon(Icons.add),
|
||||
onPressed: null,
|
||||
tooltip: 'Add',
|
||||
iconSize: 60.0,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
final Finder addButton = find.widgetWithIcon(IconButton, Icons.add);
|
||||
expect(tester.getTopRight(addButton), const Offset(800.0, 0.0));
|
||||
// It's still the size it was plus the 2 * 8dp padding from IconButton.
|
||||
expect(tester.getSize(addButton), const Size(60.0 + 2 * 8.0, 56.0));
|
||||
|
||||
final Finder shareButton = find.widgetWithIcon(IconButton, Icons.share);
|
||||
// The 20dp icon is expanded to fill the IconButton's touch target to 48dp.
|
||||
expect(tester.getSize(shareButton), const Size(48.0, 48.0));
|
||||
});
|
||||
|
||||
testWidgets('SliverAppBar default configuration', (WidgetTester tester) async {
|
||||
@ -828,7 +963,6 @@ void main() {
|
||||
});
|
||||
|
||||
testWidgets('SliverAppBar expandedHeight, pinned', (WidgetTester tester) async {
|
||||
|
||||
await tester.pumpWidget(buildSliverAppBarApp(
|
||||
pinned: true,
|
||||
expandedHeight: 128.0,
|
||||
@ -860,7 +994,6 @@ void main() {
|
||||
});
|
||||
|
||||
testWidgets('SliverAppBar expandedHeight, pinned and floating', (WidgetTester tester) async {
|
||||
|
||||
await tester.pumpWidget(buildSliverAppBarApp(
|
||||
floating: true,
|
||||
pinned: true,
|
||||
@ -1096,7 +1229,7 @@ void main() {
|
||||
expect(tabBarHeight(tester), initialTabBarHeight);
|
||||
});
|
||||
|
||||
testWidgets('SliverAppBar.medium defaults', (WidgetTester tester) async {
|
||||
testWidgets('Material3 - SliverAppBar.medium defaults', (WidgetTester tester) async {
|
||||
final ThemeData theme = ThemeData(useMaterial3: true);
|
||||
const double collapsedAppBarHeight = 64;
|
||||
const double expandedAppBarHeight = 112;
|
||||
@ -1183,7 +1316,7 @@ void main() {
|
||||
expect(tester.getSize(expandedTitleClip).height, expandedAppBarHeight - collapsedAppBarHeight);
|
||||
});
|
||||
|
||||
testWidgets('SliverAppBar.large defaults', (WidgetTester tester) async {
|
||||
testWidgets('Material3 - SliverAppBar.large defaults', (WidgetTester tester) async {
|
||||
final ThemeData theme = ThemeData(useMaterial3: true);
|
||||
const double collapsedAppBarHeight = 64;
|
||||
const double expandedAppBarHeight = 152;
|
||||
@ -1276,11 +1409,10 @@ void main() {
|
||||
expect(tester.getSize(expandedTitleClip).height, expandedAppBarHeight - collapsedAppBarHeight);
|
||||
});
|
||||
|
||||
testWidgets('AppBar uses the specified elevation or defaults to 4.0', (WidgetTester tester) async {
|
||||
final bool useMaterial3 = ThemeData().useMaterial3;
|
||||
|
||||
testWidgets('Material2 - AppBar uses the specified elevation or defaults to 4.0', (WidgetTester tester) async {
|
||||
Widget buildAppBar([double? elevation]) {
|
||||
return MaterialApp(
|
||||
theme: ThemeData(useMaterial3: false),
|
||||
home: Scaffold(
|
||||
appBar: AppBar(title: const Text('Title'), elevation: elevation),
|
||||
),
|
||||
@ -1294,7 +1426,31 @@ void main() {
|
||||
|
||||
// Default elevation should be used for the material.
|
||||
await tester.pumpWidget(buildAppBar());
|
||||
expect(getMaterial().elevation, useMaterial3 ? 0 : 4);
|
||||
expect(getMaterial().elevation, 4);
|
||||
|
||||
// AppBar should use the specified elevation.
|
||||
await tester.pumpWidget(buildAppBar(8.0));
|
||||
expect(getMaterial().elevation, 8.0);
|
||||
});
|
||||
|
||||
testWidgets('Material3 - AppBar uses the specified elevation or defaults to 0', (WidgetTester tester) async {
|
||||
Widget buildAppBar([double? elevation]) {
|
||||
return MaterialApp(
|
||||
theme: ThemeData(useMaterial3: true),
|
||||
home: Scaffold(
|
||||
appBar: AppBar(title: const Text('Title'), elevation: elevation),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Material getMaterial() => tester.widget<Material>(find.descendant(
|
||||
of: find.byType(AppBar),
|
||||
matching: find.byType(Material),
|
||||
));
|
||||
|
||||
// Default elevation should be used for the material.
|
||||
await tester.pumpWidget(buildAppBar());
|
||||
expect(getMaterial().elevation, 0);
|
||||
|
||||
// AppBar should use the specified elevation.
|
||||
await tester.pumpWidget(buildAppBar(8.0));
|
||||
@ -1334,7 +1490,7 @@ void main() {
|
||||
expect(getMaterial().elevation, 10);
|
||||
});
|
||||
|
||||
testWidgets('scrolledUnderElevation with nested scroll view', (WidgetTester tester) async {
|
||||
testWidgets('Material3 - scrolledUnderElevation with nested scroll view', (WidgetTester tester) async {
|
||||
Widget buildAppBar({double? scrolledUnderElevation}) {
|
||||
return MaterialApp(
|
||||
theme: ThemeData(useMaterial3: true),
|
||||
@ -1840,7 +1996,7 @@ void main() {
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('AppBar ink splash draw on the correct canvas', (WidgetTester tester) async {
|
||||
testWidgets('Material2 - AppBar ink splash draw on the correct canvas', (WidgetTester tester) async {
|
||||
// This is a regression test for https://github.com/flutter/flutter/issues/58665
|
||||
final Key key = UniqueKey();
|
||||
await tester.pumpWidget(
|
||||
@ -1887,6 +2043,53 @@ void main() {
|
||||
expect(painter, paints..save()..translate()..save()..translate()..circle(x: 24.0, y: 28.0));
|
||||
});
|
||||
|
||||
testWidgets('Material3 - AppBar ink splash draw on the correct canvas', (WidgetTester tester) async {
|
||||
// This is a regression test for https://github.com/flutter/flutter/issues/58665
|
||||
final Key key = UniqueKey();
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
// Test was designed against InkSplash so need to make sure that is used.
|
||||
theme: ThemeData(
|
||||
useMaterial3: true,
|
||||
splashFactory: InkSplash.splashFactory
|
||||
),
|
||||
home: Center(
|
||||
child: AppBar(
|
||||
title: const Text('Abc'),
|
||||
actions: <Widget>[
|
||||
IconButton(
|
||||
key: key,
|
||||
icon: const Icon(Icons.add_circle),
|
||||
tooltip: 'First button',
|
||||
onPressed: () {},
|
||||
),
|
||||
],
|
||||
flexibleSpace: DecoratedBox(
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
begin: Alignment.topCenter,
|
||||
end: const Alignment(-0.04, 1.0),
|
||||
colors: <Color>[Colors.blue.shade500, Colors.blue.shade800],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
final RenderObject painter = tester.renderObject(
|
||||
find.descendant(
|
||||
of: find.descendant(
|
||||
of: find.byType(AppBar),
|
||||
matching: find.byType(Stack),
|
||||
),
|
||||
matching: find.byType(Material).last,
|
||||
),
|
||||
);
|
||||
await tester.tap(find.byKey(key));
|
||||
expect(painter, paints..save()..translate()..save()..translate()..circle(x: 20.0, y: 20.0));
|
||||
});
|
||||
|
||||
testWidgets('AppBar handles loose children 0', (WidgetTester tester) async {
|
||||
final GlobalKey key = GlobalKey();
|
||||
await tester.pumpWidget(
|
||||
@ -2011,7 +2214,6 @@ void main() {
|
||||
|
||||
testWidgets('AppBar positioning of leading and trailing widgets with top padding', (WidgetTester tester) async {
|
||||
const MediaQueryData topPadding100 = MediaQueryData(padding: EdgeInsets.only(top: 100));
|
||||
|
||||
final Key leadingKey = UniqueKey();
|
||||
final Key titleKey = UniqueKey();
|
||||
final Key trailingKey = UniqueKey();
|
||||
@ -2055,7 +2257,6 @@ void main() {
|
||||
|
||||
testWidgets('SliverAppBar positioning of leading and trailing widgets with top padding', (WidgetTester tester) async {
|
||||
const MediaQueryData topPadding100 = MediaQueryData(padding: EdgeInsets.only(top: 100.0));
|
||||
|
||||
final Key leadingKey = UniqueKey();
|
||||
final Key titleKey = UniqueKey();
|
||||
final Key trailingKey = UniqueKey();
|
||||
@ -2093,7 +2294,6 @@ void main() {
|
||||
|
||||
testWidgets('SliverAppBar positioning of leading and trailing widgets with bottom padding', (WidgetTester tester) async {
|
||||
const MediaQueryData topPadding100 = MediaQueryData(padding: EdgeInsets.only(top: 100.0, bottom: 50.0));
|
||||
|
||||
final Key leadingKey = UniqueKey();
|
||||
final Key titleKey = UniqueKey();
|
||||
final Key trailingKey = UniqueKey();
|
||||
@ -2503,7 +2703,7 @@ void main() {
|
||||
semantics.dispose();
|
||||
});
|
||||
|
||||
testWidgets('AppBar draws a light system bar for a dark background', (WidgetTester tester) async {
|
||||
testWidgets('Material2 - AppBar draws a light system bar for a dark background', (WidgetTester tester) async {
|
||||
final ThemeData darkTheme = ThemeData.dark(useMaterial3: false);
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
theme: darkTheme,
|
||||
@ -2521,7 +2721,26 @@ void main() {
|
||||
));
|
||||
});
|
||||
|
||||
testWidgets('AppBar draws a dark system bar for a light background', (WidgetTester tester) async {
|
||||
testWidgets('Material3 - AppBar draws a light system bar for a dark background', (WidgetTester tester) async {
|
||||
final ThemeData darkTheme = ThemeData.dark(useMaterial3: true);
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
theme: darkTheme,
|
||||
home: Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('test'),
|
||||
),
|
||||
),
|
||||
));
|
||||
|
||||
expect(darkTheme.colorScheme.brightness, Brightness.dark);
|
||||
expect(SystemChrome.latestStyle, const SystemUiOverlayStyle(
|
||||
statusBarColor: Colors.transparent,
|
||||
statusBarBrightness: Brightness.dark,
|
||||
statusBarIconBrightness: Brightness.light,
|
||||
));
|
||||
});
|
||||
|
||||
testWidgets('Material2 - AppBar draws a dark system bar for a light background', (WidgetTester tester) async {
|
||||
final ThemeData lightTheme = ThemeData(primarySwatch: Colors.lightBlue, useMaterial3: false);
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
@ -2541,7 +2760,28 @@ void main() {
|
||||
));
|
||||
});
|
||||
|
||||
testWidgets('Default system bar brightness based on AppBar background color brightness.', (WidgetTester tester) async {
|
||||
testWidgets('Material3 - AppBar draws a dark system bar for a light background', (WidgetTester tester) async {
|
||||
final ThemeData lightTheme = ThemeData(useMaterial3: true);
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
theme: lightTheme,
|
||||
home: Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('test'),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(lightTheme.colorScheme.brightness, Brightness.light);
|
||||
expect(SystemChrome.latestStyle, const SystemUiOverlayStyle(
|
||||
statusBarColor: Colors.transparent,
|
||||
statusBarBrightness: Brightness.light,
|
||||
statusBarIconBrightness: Brightness.dark,
|
||||
));
|
||||
});
|
||||
|
||||
testWidgets('Material2 - Default system bar brightness based on AppBar background color brightness.', (WidgetTester tester) async {
|
||||
Widget buildAppBar(ThemeData theme) {
|
||||
return MaterialApp(
|
||||
theme: theme,
|
||||
@ -2592,27 +2832,94 @@ void main() {
|
||||
}
|
||||
});
|
||||
|
||||
testWidgets('Default status bar color', (WidgetTester tester) async {
|
||||
Future<void> pumpBoilerplate({required bool useMaterial3}) async {
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
key: GlobalKey(),
|
||||
theme: ThemeData.light().copyWith(
|
||||
useMaterial3: useMaterial3,
|
||||
appBarTheme: const AppBarTheme(),
|
||||
),
|
||||
home: Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('title'),
|
||||
),
|
||||
),
|
||||
testWidgets('Material3 - Default system bar brightness based on AppBar background color brightness.', (WidgetTester tester) async {
|
||||
Widget buildAppBar(ThemeData theme) {
|
||||
return MaterialApp(
|
||||
theme: theme,
|
||||
home: Scaffold(
|
||||
appBar: AppBar(title: const Text('Title')),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
await pumpBoilerplate(useMaterial3: false);
|
||||
// Using a light theme.
|
||||
{
|
||||
await tester.pumpWidget(buildAppBar(ThemeData(useMaterial3: true)));
|
||||
final Material appBarMaterial = tester.widget<Material>(
|
||||
find.descendant(
|
||||
of: find.byType(AppBar),
|
||||
matching: find.byType(Material),
|
||||
),
|
||||
);
|
||||
final Brightness appBarBrightness = ThemeData.estimateBrightnessForColor(appBarMaterial.color!);
|
||||
final Brightness onAppBarBrightness = appBarBrightness == Brightness.light
|
||||
? Brightness.dark
|
||||
: Brightness.light;
|
||||
|
||||
expect(SystemChrome.latestStyle, SystemUiOverlayStyle(
|
||||
statusBarColor: Colors.transparent,
|
||||
statusBarBrightness: appBarBrightness,
|
||||
statusBarIconBrightness: onAppBarBrightness,
|
||||
));
|
||||
}
|
||||
|
||||
// Using a dark theme.
|
||||
{
|
||||
await tester.pumpWidget(buildAppBar(ThemeData.dark(useMaterial3: true)));
|
||||
final Material appBarMaterial = tester.widget<Material>(
|
||||
find.descendant(
|
||||
of: find.byType(AppBar),
|
||||
matching: find.byType(Material),
|
||||
),
|
||||
);
|
||||
final Brightness appBarBrightness = ThemeData.estimateBrightnessForColor(appBarMaterial.color!);
|
||||
final Brightness onAppBarBrightness = appBarBrightness == Brightness.light
|
||||
? Brightness.dark
|
||||
: Brightness.light;
|
||||
|
||||
expect(SystemChrome.latestStyle, SystemUiOverlayStyle(
|
||||
statusBarColor: Colors.transparent,
|
||||
statusBarBrightness: appBarBrightness,
|
||||
statusBarIconBrightness: onAppBarBrightness,
|
||||
));
|
||||
}
|
||||
});
|
||||
|
||||
testWidgets('Material2 - Default status bar color', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
key: GlobalKey(),
|
||||
theme: ThemeData.light().copyWith(
|
||||
useMaterial3: false,
|
||||
appBarTheme: const AppBarTheme(),
|
||||
),
|
||||
home: Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('title'),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(SystemChrome.latestStyle!.statusBarColor, null);
|
||||
await pumpBoilerplate(useMaterial3: true);
|
||||
});
|
||||
|
||||
testWidgets('Material3 - Default status bar color', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
key: GlobalKey(),
|
||||
theme: ThemeData.light().copyWith(
|
||||
useMaterial3: true,
|
||||
appBarTheme: const AppBarTheme(),
|
||||
),
|
||||
home: Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('title'),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(SystemChrome.latestStyle!.statusBarColor, Colors.transparent);
|
||||
});
|
||||
|
||||
@ -3167,8 +3474,8 @@ void main() {
|
||||
});
|
||||
|
||||
// Regression test for https://github.com/flutter/flutter/issues/107305
|
||||
group('Icons are colored correctly by IconTheme and ActionIconTheme in M3', () {
|
||||
testWidgets('Icons and IconButtons are colored by IconTheme in M3', (WidgetTester tester) async {
|
||||
group('Material3 - Icons are colored correctly by IconTheme and ActionIconTheme', () {
|
||||
testWidgets('Material3 - Icons and IconButtons are colored by IconTheme', (WidgetTester tester) async {
|
||||
const Color iconColor = Color(0xff00ff00);
|
||||
final Key leadingIconKey = UniqueKey();
|
||||
final Key actionIconKey = UniqueKey();
|
||||
@ -3200,7 +3507,7 @@ void main() {
|
||||
expect(actionIconButtonColor(), iconColor);
|
||||
});
|
||||
|
||||
testWidgets('Action icons and IconButtons are colored by ActionIconTheme - M3', (WidgetTester tester) async {
|
||||
testWidgets('Material3 - Action icons and IconButtons are colored by ActionIconTheme', (WidgetTester tester) async {
|
||||
final ThemeData themeData = ThemeData.from(
|
||||
colorScheme: const ColorScheme.light(),
|
||||
useMaterial3: true,
|
||||
@ -3236,7 +3543,7 @@ void main() {
|
||||
expect(actionIconButtonColor(), actionsIconColor);
|
||||
});
|
||||
|
||||
testWidgets('The actionIconTheme property overrides iconTheme - M3', (WidgetTester tester) async {
|
||||
testWidgets('Material3 - The actionIconTheme property overrides iconTheme', (WidgetTester tester) async {
|
||||
final ThemeData themeData = ThemeData.from(
|
||||
colorScheme: const ColorScheme.light(),
|
||||
useMaterial3: true,
|
||||
@ -3274,7 +3581,7 @@ void main() {
|
||||
expect(actionIconButtonColor(), actionsIconColor);
|
||||
});
|
||||
|
||||
testWidgets('AppBar.iconTheme should override any IconButtonTheme present in the theme - M3', (WidgetTester tester) async {
|
||||
testWidgets('Material3 - AppBar.iconTheme should override any IconButtonTheme present in the theme', (WidgetTester tester) async {
|
||||
final ThemeData themeData = ThemeData(
|
||||
iconButtonTheme: IconButtonThemeData(
|
||||
style: IconButton.styleFrom(
|
||||
@ -3313,7 +3620,7 @@ void main() {
|
||||
expect(actionIconButtonSize(), 30.0);
|
||||
});
|
||||
|
||||
testWidgets('AppBar.iconTheme should override any IconButtonTheme present in the theme for widgets containing an iconButton - M3', (WidgetTester tester) async {
|
||||
testWidgets('Material3 - AppBar.iconTheme should override any IconButtonTheme present in the theme for widgets containing an iconButton', (WidgetTester tester) async {
|
||||
final ThemeData themeData = ThemeData(
|
||||
iconButtonTheme: IconButtonThemeData(
|
||||
style: IconButton.styleFrom(
|
||||
@ -3346,7 +3653,7 @@ void main() {
|
||||
|
||||
});
|
||||
|
||||
testWidgets('AppBar.actionsIconTheme should override any IconButtonTheme present in the theme - M3', (WidgetTester tester) async {
|
||||
testWidgets('Material3 - AppBar.actionsIconTheme should override any IconButtonTheme present in the theme', (WidgetTester tester) async {
|
||||
final ThemeData themeData = ThemeData(
|
||||
iconButtonTheme: IconButtonThemeData(
|
||||
style: IconButton.styleFrom(
|
||||
@ -3386,7 +3693,7 @@ void main() {
|
||||
expect(actionIconButtonSize(), 30.0);
|
||||
});
|
||||
|
||||
testWidgets('AppBar.actionsIconTheme should override any IconButtonTheme present in the theme for widgets containing an iconButton - M3', (WidgetTester tester) async {
|
||||
testWidgets('Material3 - AppBar.actionsIconTheme should override any IconButtonTheme present in the theme for widgets containing an iconButton', (WidgetTester tester) async {
|
||||
final ThemeData themeData = ThemeData(
|
||||
iconButtonTheme: IconButtonThemeData(
|
||||
style: IconButton.styleFrom(
|
||||
@ -3420,7 +3727,7 @@ void main() {
|
||||
expect(actionIconButtonSize(), 30.0);
|
||||
});
|
||||
|
||||
testWidgets('The foregroundColor property of the AppBar overrides any IconButtonTheme present in the theme - M3', (WidgetTester tester) async {
|
||||
testWidgets('Material3 - The foregroundColor property of the AppBar overrides any IconButtonTheme present in the theme', (WidgetTester tester) async {
|
||||
final ThemeData themeData = ThemeData(
|
||||
iconButtonTheme: IconButtonThemeData(
|
||||
style: IconButton.styleFrom(
|
||||
@ -5104,7 +5411,7 @@ void main() {
|
||||
// support is deprecated and the APIs are removed, these tests
|
||||
// can be deleted.
|
||||
|
||||
testWidgets('SliverAppBar.medium defaults', (WidgetTester tester) async {
|
||||
testWidgets('Material2 - SliverAppBar.medium defaults', (WidgetTester tester) async {
|
||||
final ThemeData theme = ThemeData(useMaterial3: false);
|
||||
const double collapsedAppBarHeight = 64;
|
||||
const double expandedAppBarHeight = 112;
|
||||
@ -5188,13 +5495,13 @@ void main() {
|
||||
expect(tester.getSize(expandedTitleClip).height, expandedAppBarHeight - collapsedAppBarHeight);
|
||||
});
|
||||
|
||||
testWidgets('SliverAppBar.large defaults', (WidgetTester tester) async {
|
||||
testWidgets('Material2 - SliverAppBar.large defaults', (WidgetTester tester) async {
|
||||
final ThemeData theme = ThemeData(useMaterial3: false);
|
||||
const double collapsedAppBarHeight = 64;
|
||||
const double expandedAppBarHeight = 152;
|
||||
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
theme: ThemeData(useMaterial3: false),
|
||||
theme: theme,
|
||||
home: Scaffold(
|
||||
body: CustomScrollView(
|
||||
primary: true,
|
||||
|
||||
@ -42,9 +42,8 @@ void main() {
|
||||
expect(identical(AppBarTheme.lerp(data, data, 0.5), data), true);
|
||||
});
|
||||
|
||||
testWidgets('Passing no AppBarTheme returns defaults', (WidgetTester tester) async {
|
||||
final ThemeData theme = ThemeData();
|
||||
final bool material3 = theme.useMaterial3;
|
||||
testWidgets('Material2 - Passing no AppBarTheme returns defaults', (WidgetTester tester) async {
|
||||
final ThemeData theme = ThemeData(useMaterial3: false);
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
theme: theme,
|
||||
@ -64,35 +63,58 @@ void main() {
|
||||
final RichText actionIconText = _getAppBarIconRichText(tester);
|
||||
final DefaultTextStyle text = _getAppBarText(tester);
|
||||
|
||||
if (theme.useMaterial3) {
|
||||
expect(SystemChrome.latestStyle!.statusBarBrightness, Brightness.light);
|
||||
expect(widget.color, theme.colorScheme.surface);
|
||||
expect(widget.elevation, 0);
|
||||
expect(widget.shadowColor, material3 ? Colors.transparent : null);
|
||||
expect(widget.surfaceTintColor, theme.colorScheme.surfaceTint);
|
||||
expect(widget.shape, null);
|
||||
expect(iconTheme.data, IconThemeData(color: theme.colorScheme.onSurface, size: 24));
|
||||
expect(actionsIconTheme.data, IconThemeData(color: theme.colorScheme.onSurfaceVariant, size: 24));
|
||||
expect(actionIconText.text.style!.color, material3 ? theme.colorScheme.onSurfaceVariant : Colors.black);
|
||||
expect(text.style, material3
|
||||
? Typography.material2021().englishLike.bodyMedium!.merge(Typography.material2021().black.bodyMedium).copyWith(color: theme.colorScheme.onSurface, decorationColor: theme.colorScheme.onSurface)
|
||||
: Typography.material2021().englishLike.bodyMedium!.merge(Typography.material2021().black.bodyMedium).copyWith(color: theme.colorScheme.onSurface));
|
||||
expect(tester.getSize(find.byType(AppBar)).height, kToolbarHeight);
|
||||
expect(tester.getSize(find.byType(AppBar)).width, 800);
|
||||
} else {
|
||||
expect(SystemChrome.latestStyle!.statusBarBrightness, SystemUiOverlayStyle.light.statusBarBrightness);
|
||||
expect(widget.color, Colors.blue);
|
||||
expect(widget.elevation, 4.0);
|
||||
expect(widget.shadowColor, Colors.black);
|
||||
expect(widget.surfaceTintColor, null);
|
||||
expect(widget.shape, null);
|
||||
expect(iconTheme.data, const IconThemeData(color: Colors.white));
|
||||
expect(actionsIconTheme.data, const IconThemeData(color: Colors.white));
|
||||
expect(actionIconText.text.style!.color, Colors.white);
|
||||
expect(text.style, Typography.material2014().englishLike.bodyMedium!.merge(Typography.material2014().white.bodyMedium));
|
||||
expect(tester.getSize(find.byType(AppBar)).height, kToolbarHeight);
|
||||
expect(tester.getSize(find.byType(AppBar)).width, 800);
|
||||
}
|
||||
expect(SystemChrome.latestStyle!.statusBarBrightness, SystemUiOverlayStyle.light.statusBarBrightness);
|
||||
expect(widget.color, Colors.blue);
|
||||
expect(widget.elevation, 4.0);
|
||||
expect(widget.shadowColor, Colors.black);
|
||||
expect(widget.surfaceTintColor, null);
|
||||
expect(widget.shape, null);
|
||||
expect(iconTheme.data, const IconThemeData(color: Colors.white));
|
||||
expect(actionsIconTheme.data, const IconThemeData(color: Colors.white));
|
||||
expect(actionIconText.text.style!.color, Colors.white);
|
||||
expect(text.style, Typography.material2014().englishLike.bodyMedium!.merge(Typography.material2014().white.bodyMedium));
|
||||
expect(tester.getSize(find.byType(AppBar)).height, kToolbarHeight);
|
||||
expect(tester.getSize(find.byType(AppBar)).width, 800);
|
||||
});
|
||||
|
||||
testWidgets('Material3 - Passing no AppBarTheme returns defaults', (WidgetTester tester) async {
|
||||
final ThemeData theme = ThemeData(useMaterial3: true);
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
theme: theme,
|
||||
home: Scaffold(
|
||||
appBar: AppBar(
|
||||
actions: <Widget>[
|
||||
IconButton(icon: const Icon(Icons.share), onPressed: () { }),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
final Material widget = _getAppBarMaterial(tester);
|
||||
final IconTheme iconTheme = _getAppBarIconTheme(tester);
|
||||
final IconTheme actionsIconTheme = _getAppBarActionsIconTheme(tester);
|
||||
final RichText actionIconText = _getAppBarIconRichText(tester);
|
||||
final DefaultTextStyle text = _getAppBarText(tester);
|
||||
|
||||
expect(SystemChrome.latestStyle!.statusBarBrightness, Brightness.light);
|
||||
expect(widget.color, theme.colorScheme.surface);
|
||||
expect(widget.elevation, 0);
|
||||
expect(widget.shadowColor, Colors.transparent);
|
||||
expect(widget.surfaceTintColor, theme.colorScheme.surfaceTint);
|
||||
expect(widget.shape, null);
|
||||
expect(iconTheme.data, IconThemeData(color: theme.colorScheme.onSurface, size: 24));
|
||||
expect(actionsIconTheme.data, IconThemeData(color: theme.colorScheme.onSurfaceVariant, size: 24));
|
||||
expect(actionIconText.text.style!.color, theme.colorScheme.onSurfaceVariant);
|
||||
expect(
|
||||
text.style,
|
||||
Typography.material2021().englishLike.bodyMedium!
|
||||
.merge(Typography.material2021().black.bodyMedium)
|
||||
.copyWith(color: theme.colorScheme.onSurface, decorationColor: theme.colorScheme.onSurface),
|
||||
);
|
||||
expect(tester.getSize(find.byType(AppBar)).height, kToolbarHeight);
|
||||
expect(tester.getSize(find.byType(AppBar)).width, 800);
|
||||
});
|
||||
|
||||
testWidgets('AppBar uses values from AppBarTheme', (WidgetTester tester) async {
|
||||
@ -242,9 +264,9 @@ void main() {
|
||||
expect(text.style, appBarTheme.toolbarTextStyle);
|
||||
});
|
||||
|
||||
testWidgets('ThemeData colorScheme is used when no AppBarTheme is set', (WidgetTester tester) async {
|
||||
final ThemeData lightTheme = ThemeData.from(colorScheme: const ColorScheme.light());
|
||||
final ThemeData darkTheme = ThemeData.from(colorScheme: const ColorScheme.dark());
|
||||
testWidgets('Material2 - ThemeData colorScheme is used when no AppBarTheme is set', (WidgetTester tester) async {
|
||||
final ThemeData lightTheme = ThemeData.from(colorScheme: const ColorScheme.light(), useMaterial3: false);
|
||||
final ThemeData darkTheme = ThemeData.from(colorScheme: const ColorScheme.dark(), useMaterial3: false);
|
||||
Widget buildFrame(ThemeData appTheme) {
|
||||
return MaterialApp(
|
||||
theme: appTheme,
|
||||
@ -262,121 +284,132 @@ void main() {
|
||||
);
|
||||
}
|
||||
|
||||
if (lightTheme.useMaterial3) {
|
||||
// M3 AppBar defaults for light themes:
|
||||
// - elevation: 0
|
||||
// - shadow color: Colors.transparent
|
||||
// - surface tint color: ColorScheme.surfaceTint
|
||||
// - background color: ColorScheme.surface
|
||||
// - foreground color: ColorScheme.onSurface
|
||||
// - actions text: style bodyMedium, foreground color
|
||||
// - status bar brightness: light (based on color scheme brightness)
|
||||
{
|
||||
await tester.pumpWidget(buildFrame(lightTheme));
|
||||
// AppBar M2 defaults for light themes:
|
||||
// - elevation: 4
|
||||
// - shadow color: black
|
||||
// - surface tint color: null
|
||||
// - background color: ColorScheme.primary
|
||||
// - foreground color: ColorScheme.onPrimary
|
||||
// - actions text: style bodyMedium, foreground color
|
||||
// - status bar brightness: light (based on color scheme brightness)
|
||||
await tester.pumpWidget(buildFrame(lightTheme));
|
||||
|
||||
final Material widget = _getAppBarMaterial(tester);
|
||||
final IconTheme iconTheme = _getAppBarIconTheme(tester);
|
||||
final IconTheme actionsIconTheme = _getAppBarActionsIconTheme(tester);
|
||||
final RichText actionIconText = _getAppBarIconRichText(tester);
|
||||
final DefaultTextStyle text = _getAppBarText(tester);
|
||||
Material widget = _getAppBarMaterial(tester);
|
||||
IconTheme iconTheme = _getAppBarIconTheme(tester);
|
||||
IconTheme actionsIconTheme = _getAppBarActionsIconTheme(tester);
|
||||
RichText actionIconText = _getAppBarIconRichText(tester);
|
||||
DefaultTextStyle text = _getAppBarText(tester);
|
||||
|
||||
expect(SystemChrome.latestStyle!.statusBarBrightness, Brightness.light);
|
||||
expect(widget.color, lightTheme.colorScheme.surface);
|
||||
expect(widget.elevation, 0);
|
||||
expect(widget.shadowColor, Colors.transparent);
|
||||
expect(widget.surfaceTintColor, lightTheme.colorScheme.surfaceTint);
|
||||
expect(iconTheme.data.color, lightTheme.colorScheme.onSurface);
|
||||
expect(actionsIconTheme.data.color, lightTheme.colorScheme.onSurface);
|
||||
expect(actionIconText.text.style!.color, lightTheme.colorScheme.onSurface);
|
||||
expect(text.style, Typography.material2021().englishLike.bodyMedium!.merge(Typography.material2021().black.bodyMedium).copyWith(color: lightTheme.colorScheme.onSurface));
|
||||
}
|
||||
expect(SystemChrome.latestStyle!.statusBarBrightness, SystemUiOverlayStyle.light.statusBarBrightness);
|
||||
expect(widget.color, lightTheme.colorScheme.primary);
|
||||
expect(widget.elevation, 4.0);
|
||||
expect(widget.shadowColor, Colors.black);
|
||||
expect(widget.surfaceTintColor, null);
|
||||
expect(iconTheme.data.color, lightTheme.colorScheme.onPrimary);
|
||||
expect(actionsIconTheme.data.color, lightTheme.colorScheme.onPrimary);
|
||||
expect(actionIconText.text.style!.color, lightTheme.colorScheme.onPrimary);
|
||||
expect(text.style, Typography.material2014().englishLike.bodyMedium!.merge(Typography.material2014().black.bodyMedium).copyWith(color: lightTheme.colorScheme.onPrimary));
|
||||
|
||||
// M3 AppBar defaults for dark themes:
|
||||
// - elevation: 0
|
||||
// - shadow color: Colors.transparent
|
||||
// - surface tint color: ColorScheme.surfaceTint
|
||||
// - background color: ColorScheme.surface
|
||||
// - foreground color: ColorScheme.onSurface
|
||||
// - actions text: style bodyMedium, foreground color
|
||||
// - status bar brightness: dark (based on background color)
|
||||
{
|
||||
await tester.pumpWidget(buildFrame(darkTheme));
|
||||
await tester.pumpAndSettle(); // Theme change animation
|
||||
// AppBar M2 defaults for dark themes:
|
||||
// - elevation: 4
|
||||
// - shadow color: black
|
||||
// - surface tint color: null
|
||||
// - background color: ColorScheme.surface
|
||||
// - foreground color: ColorScheme.onSurface
|
||||
// - actions text: style bodyMedium, foreground color
|
||||
// - status bar brightness: dark (based on background color)
|
||||
await tester.pumpWidget(buildFrame(darkTheme));
|
||||
await tester.pumpAndSettle(); // Theme change animation
|
||||
|
||||
final Material widget = _getAppBarMaterial(tester);
|
||||
final IconTheme iconTheme = _getAppBarIconTheme(tester);
|
||||
final IconTheme actionsIconTheme = _getAppBarActionsIconTheme(tester);
|
||||
final RichText actionIconText = _getAppBarIconRichText(tester);
|
||||
final DefaultTextStyle text = _getAppBarText(tester);
|
||||
widget = _getAppBarMaterial(tester);
|
||||
iconTheme = _getAppBarIconTheme(tester);
|
||||
actionsIconTheme = _getAppBarActionsIconTheme(tester);
|
||||
actionIconText = _getAppBarIconRichText(tester);
|
||||
text = _getAppBarText(tester);
|
||||
|
||||
expect(SystemChrome.latestStyle!.statusBarBrightness, Brightness.dark);
|
||||
expect(widget.color, darkTheme.colorScheme.surface);
|
||||
expect(widget.elevation, 0);
|
||||
expect(widget.shadowColor, Colors.transparent);
|
||||
expect(widget.surfaceTintColor, darkTheme.colorScheme.surfaceTint);
|
||||
expect(iconTheme.data.color, darkTheme.colorScheme.onSurface);
|
||||
expect(actionsIconTheme.data.color, darkTheme.colorScheme.onSurface);
|
||||
expect(actionIconText.text.style!.color, darkTheme.colorScheme.onSurface);
|
||||
expect(text.style, Typography.material2021().englishLike.bodyMedium!.merge(Typography.material2021().black.bodyMedium).copyWith(color: darkTheme.colorScheme.onSurface, decorationColor: darkTheme.colorScheme.onSurface));
|
||||
}
|
||||
} else {
|
||||
// AppBar M2 defaults for light themes:
|
||||
// - elevation: 4
|
||||
// - shadow color: black
|
||||
// - surface tint color: null
|
||||
// - background color: ColorScheme.primary
|
||||
// - foreground color: ColorScheme.onPrimary
|
||||
// - actions text: style bodyMedium, foreground color
|
||||
// - status bar brightness: light (based on color scheme brightness)
|
||||
{
|
||||
await tester.pumpWidget(buildFrame(lightTheme));
|
||||
expect(SystemChrome.latestStyle!.statusBarBrightness, SystemUiOverlayStyle.light.statusBarBrightness);
|
||||
expect(widget.color, darkTheme.colorScheme.surface);
|
||||
expect(widget.elevation, 4.0);
|
||||
expect(widget.shadowColor, Colors.black);
|
||||
expect(widget.surfaceTintColor, null);
|
||||
expect(iconTheme.data.color, darkTheme.colorScheme.onSurface);
|
||||
expect(actionsIconTheme.data.color, darkTheme.colorScheme.onSurface);
|
||||
expect(actionIconText.text.style!.color, darkTheme.colorScheme.onSurface);
|
||||
expect(text.style, Typography.material2014().englishLike.bodyMedium!.merge(Typography.material2014().black.bodyMedium).copyWith(color: darkTheme.colorScheme.onSurface));
|
||||
});
|
||||
|
||||
final Material widget = _getAppBarMaterial(tester);
|
||||
final IconTheme iconTheme = _getAppBarIconTheme(tester);
|
||||
final IconTheme actionsIconTheme = _getAppBarActionsIconTheme(tester);
|
||||
final RichText actionIconText = _getAppBarIconRichText(tester);
|
||||
final DefaultTextStyle text = _getAppBarText(tester);
|
||||
|
||||
expect(SystemChrome.latestStyle!.statusBarBrightness, SystemUiOverlayStyle.light.statusBarBrightness);
|
||||
expect(widget.color, lightTheme.colorScheme.primary);
|
||||
expect(widget.elevation, 4.0);
|
||||
expect(widget.shadowColor, Colors.black);
|
||||
expect(widget.surfaceTintColor, null);
|
||||
expect(iconTheme.data.color, lightTheme.colorScheme.onPrimary);
|
||||
expect(actionsIconTheme.data.color, lightTheme.colorScheme.onPrimary);
|
||||
expect(actionIconText.text.style!.color, lightTheme.colorScheme.onPrimary);
|
||||
expect(text.style, Typography.material2014().englishLike.bodyMedium!.merge(Typography.material2014().black.bodyMedium).copyWith(color: lightTheme.colorScheme.onPrimary));
|
||||
}
|
||||
|
||||
// AppBar M2 defaults for dark themes:
|
||||
// - elevation: 4
|
||||
// - shadow color: black
|
||||
// - surface tint color: null
|
||||
// - background color: ColorScheme.surface
|
||||
// - foreground color: ColorScheme.onSurface
|
||||
// - actions text: style bodyMedium, foreground color
|
||||
// - status bar brightness: dark (based on background color)
|
||||
{
|
||||
await tester.pumpWidget(buildFrame(darkTheme));
|
||||
await tester.pumpAndSettle(); // Theme change animation
|
||||
|
||||
final Material widget = _getAppBarMaterial(tester);
|
||||
final IconTheme iconTheme = _getAppBarIconTheme(tester);
|
||||
final IconTheme actionsIconTheme = _getAppBarActionsIconTheme(tester);
|
||||
final RichText actionIconText = _getAppBarIconRichText(tester);
|
||||
final DefaultTextStyle text = _getAppBarText(tester);
|
||||
|
||||
expect(SystemChrome.latestStyle!.statusBarBrightness, SystemUiOverlayStyle.light.statusBarBrightness);
|
||||
expect(widget.color, darkTheme.colorScheme.surface);
|
||||
expect(widget.elevation, 4.0);
|
||||
expect(widget.shadowColor, Colors.black);
|
||||
expect(widget.surfaceTintColor, null);
|
||||
expect(iconTheme.data.color, darkTheme.colorScheme.onSurface);
|
||||
expect(actionsIconTheme.data.color, darkTheme.colorScheme.onSurface);
|
||||
expect(actionIconText.text.style!.color, darkTheme.colorScheme.onSurface);
|
||||
expect(text.style, Typography.material2014().englishLike.bodyMedium!.merge(Typography.material2014().black.bodyMedium).copyWith(color: darkTheme.colorScheme.onSurface));
|
||||
}
|
||||
testWidgets('Material3 - ThemeData colorScheme is used when no AppBarTheme is set', (WidgetTester tester) async {
|
||||
final ThemeData lightTheme = ThemeData.from(colorScheme: const ColorScheme.light(), useMaterial3: true);
|
||||
final ThemeData darkTheme = ThemeData.from(colorScheme: const ColorScheme.dark(), useMaterial3: true);
|
||||
Widget buildFrame(ThemeData appTheme) {
|
||||
return MaterialApp(
|
||||
theme: appTheme,
|
||||
home: Builder(
|
||||
builder: (BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
actions: <Widget>[
|
||||
IconButton(icon: const Icon(Icons.share), onPressed: () { }),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// M3 AppBar defaults for light themes:
|
||||
// - elevation: 0
|
||||
// - shadow color: Colors.transparent
|
||||
// - surface tint color: ColorScheme.surfaceTint
|
||||
// - background color: ColorScheme.surface
|
||||
// - foreground color: ColorScheme.onSurface
|
||||
// - actions text: style bodyMedium, foreground color
|
||||
// - status bar brightness: light (based on color scheme brightness)
|
||||
await tester.pumpWidget(buildFrame(lightTheme));
|
||||
|
||||
Material widget = _getAppBarMaterial(tester);
|
||||
IconTheme iconTheme = _getAppBarIconTheme(tester);
|
||||
IconTheme actionsIconTheme = _getAppBarActionsIconTheme(tester);
|
||||
RichText actionIconText = _getAppBarIconRichText(tester);
|
||||
DefaultTextStyle text = _getAppBarText(tester);
|
||||
|
||||
expect(SystemChrome.latestStyle!.statusBarBrightness, Brightness.light);
|
||||
expect(widget.color, lightTheme.colorScheme.surface);
|
||||
expect(widget.elevation, 0);
|
||||
expect(widget.shadowColor, Colors.transparent);
|
||||
expect(widget.surfaceTintColor, lightTheme.colorScheme.surfaceTint);
|
||||
expect(iconTheme.data.color, lightTheme.colorScheme.onSurface);
|
||||
expect(actionsIconTheme.data.color, lightTheme.colorScheme.onSurface);
|
||||
expect(actionIconText.text.style!.color, lightTheme.colorScheme.onSurface);
|
||||
expect(text.style, Typography.material2021().englishLike.bodyMedium!.merge(Typography.material2021().black.bodyMedium).copyWith(color: lightTheme.colorScheme.onSurface));
|
||||
|
||||
// M3 AppBar defaults for dark themes:
|
||||
// - elevation: 0
|
||||
// - shadow color: Colors.transparent
|
||||
// - surface tint color: ColorScheme.surfaceTint
|
||||
// - background color: ColorScheme.surface
|
||||
// - foreground color: ColorScheme.onSurface
|
||||
// - actions text: style bodyMedium, foreground color
|
||||
// - status bar brightness: dark (based on background color)
|
||||
await tester.pumpWidget(buildFrame(darkTheme));
|
||||
await tester.pumpAndSettle(); // Theme change animation
|
||||
|
||||
widget = _getAppBarMaterial(tester);
|
||||
iconTheme = _getAppBarIconTheme(tester);
|
||||
actionsIconTheme = _getAppBarActionsIconTheme(tester);
|
||||
actionIconText = _getAppBarIconRichText(tester);
|
||||
text = _getAppBarText(tester);
|
||||
|
||||
expect(SystemChrome.latestStyle!.statusBarBrightness, Brightness.dark);
|
||||
expect(widget.color, darkTheme.colorScheme.surface);
|
||||
expect(widget.elevation, 0);
|
||||
expect(widget.shadowColor, Colors.transparent);
|
||||
expect(widget.surfaceTintColor, darkTheme.colorScheme.surfaceTint);
|
||||
expect(iconTheme.data.color, darkTheme.colorScheme.onSurface);
|
||||
expect(actionsIconTheme.data.color, darkTheme.colorScheme.onSurface);
|
||||
expect(actionIconText.text.style!.color, darkTheme.colorScheme.onSurface);
|
||||
expect(text.style, Typography.material2021().englishLike.bodyMedium!.merge(Typography.material2021().black.bodyMedium).copyWith(color: darkTheme.colorScheme.onSurface, decorationColor: darkTheme.colorScheme.onSurface));
|
||||
});
|
||||
|
||||
testWidgets('AppBar iconTheme with color=null defers to outer IconTheme', (WidgetTester tester) async {
|
||||
@ -384,7 +417,7 @@ void main() {
|
||||
|
||||
Widget buildFrame({ Color? appIconColor, Color? appBarIconColor }) {
|
||||
return MaterialApp(
|
||||
theme: ThemeData.from(useMaterial3: false, colorScheme: const ColorScheme.light()),
|
||||
theme: ThemeData.from(colorScheme: const ColorScheme.light()),
|
||||
home: IconTheme(
|
||||
data: IconThemeData(color: appIconColor),
|
||||
child: Builder(
|
||||
@ -493,7 +526,7 @@ void main() {
|
||||
expect(appBar.surfaceTintColor, Colors.yellow);
|
||||
});
|
||||
|
||||
testWidgets('AppBarTheme.iconTheme.color takes priority over IconButtonTheme.foregroundColor - M3', (WidgetTester tester) async {
|
||||
testWidgets('Material3 - AppBarTheme.iconTheme.color takes priority over IconButtonTheme.foregroundColor', (WidgetTester tester) async {
|
||||
const IconThemeData overallIconTheme = IconThemeData(color: Colors.yellow);
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
theme: ThemeData(
|
||||
@ -519,7 +552,7 @@ void main() {
|
||||
expect(actionIconButtonColor, overallIconTheme.color);
|
||||
});
|
||||
|
||||
testWidgets('AppBarTheme.iconTheme.size takes priority over IconButtonTheme.iconSize - M3', (WidgetTester tester) async {
|
||||
testWidgets('Material3 - AppBarTheme.iconTheme.size takes priority over IconButtonTheme.iconSize', (WidgetTester tester) async {
|
||||
const IconThemeData overallIconTheme = IconThemeData(size: 30.0);
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
theme: ThemeData(
|
||||
@ -546,7 +579,7 @@ void main() {
|
||||
});
|
||||
|
||||
|
||||
testWidgets('AppBarTheme.actionsIconTheme.color takes priority over IconButtonTheme.foregroundColor - M3', (WidgetTester tester) async {
|
||||
testWidgets('Material3 - AppBarTheme.actionsIconTheme.color takes priority over IconButtonTheme.foregroundColor', (WidgetTester tester) async {
|
||||
const IconThemeData actionsIconTheme = IconThemeData(color: Colors.yellow);
|
||||
final IconButtonThemeData iconButtonTheme = IconButtonThemeData(
|
||||
style: IconButton.styleFrom(foregroundColor: Colors.red),
|
||||
@ -574,7 +607,7 @@ void main() {
|
||||
expect(actionIconButtonColor, actionsIconTheme.color);
|
||||
});
|
||||
|
||||
testWidgets('AppBarTheme.actionsIconTheme.size takes priority over IconButtonTheme.iconSize - M3', (WidgetTester tester) async {
|
||||
testWidgets('Material3 - AppBarTheme.actionsIconTheme.size takes priority over IconButtonTheme.iconSize', (WidgetTester tester) async {
|
||||
const IconThemeData actionsIconTheme = IconThemeData(size: 30.0);
|
||||
final IconButtonThemeData iconButtonTheme = IconButtonThemeData(
|
||||
style: IconButton.styleFrom(iconSize: 32.0),
|
||||
@ -601,7 +634,7 @@ void main() {
|
||||
expect(actionIconButtonSize, actionsIconTheme.size);
|
||||
});
|
||||
|
||||
testWidgets('AppBarTheme.foregroundColor takes priority over IconButtonTheme.foregroundColor - M3', (WidgetTester tester) async {
|
||||
testWidgets('Material3 - AppBarTheme.foregroundColor takes priority over IconButtonTheme.foregroundColor', (WidgetTester tester) async {
|
||||
final IconButtonThemeData iconButtonTheme = IconButtonThemeData(
|
||||
style: IconButton.styleFrom(foregroundColor: Colors.red),
|
||||
);
|
||||
@ -1027,12 +1060,22 @@ void main() {
|
||||
testWidgets('AppBarTheme implements debugFillProperties', (WidgetTester tester) async {
|
||||
final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
|
||||
const AppBarTheme(
|
||||
backgroundColor: Color(0xff000001),
|
||||
backgroundColor: Color(0xff000000),
|
||||
foregroundColor: Color(0xff000001),
|
||||
elevation: 8.0,
|
||||
scrolledUnderElevation: 3,
|
||||
shadowColor: Color(0xff000002),
|
||||
surfaceTintColor: Color(0xff000003),
|
||||
shape: StadiumBorder(),
|
||||
iconTheme: IconThemeData(color: Color(0xff000004)),
|
||||
centerTitle: true,
|
||||
titleSpacing: 40.0,
|
||||
toolbarHeight: 96,
|
||||
toolbarTextStyle: TextStyle(color: Color(0xff000005)),
|
||||
titleTextStyle: TextStyle(color: Color(0xff000006)),
|
||||
systemOverlayStyle: SystemUiOverlayStyle(
|
||||
systemNavigationBarColor: Color(0xff000007),
|
||||
),
|
||||
).debugFillProperties(builder);
|
||||
|
||||
final List<String> description = builder.properties
|
||||
@ -1040,14 +1083,26 @@ void main() {
|
||||
.map((DiagnosticsNode node) => node.toString())
|
||||
.toList();
|
||||
|
||||
expect(description, <String>[
|
||||
'backgroundColor: Color(0xff000001)',
|
||||
'elevation: 8.0',
|
||||
'shadowColor: Color(0xff000002)',
|
||||
'surfaceTintColor: Color(0xff000003)',
|
||||
'centerTitle: true',
|
||||
'titleSpacing: 40.0',
|
||||
]);
|
||||
expect(
|
||||
description,
|
||||
equalsIgnoringHashCodes(
|
||||
<String>[
|
||||
'backgroundColor: Color(0xff000000)',
|
||||
'foregroundColor: Color(0xff000001)',
|
||||
'elevation: 8.0',
|
||||
'scrolledUnderElevation: 3.0',
|
||||
'shadowColor: Color(0xff000002)',
|
||||
'surfaceTintColor: Color(0xff000003)',
|
||||
'shape: StadiumBorder(BorderSide(width: 0.0, style: none))',
|
||||
'iconTheme: IconThemeData#00000(color: Color(0xff000004))',
|
||||
'centerTitle: true',
|
||||
'titleSpacing: 40.0',
|
||||
'toolbarHeight: 96.0',
|
||||
'toolbarTextStyle: TextStyle(inherit: true, color: Color(0xff000005))',
|
||||
'titleTextStyle: TextStyle(inherit: true, color: Color(0xff000006))'
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
// On the web, Dart doubles and ints are backed by the same kind of object because
|
||||
// JavaScript does not support integers. So, the Dart double "4.0" is identical
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user