Widgets app refactor (#22269)
* Refactor of cupertino/material/widgets app
* update docs
* Update tests for const
diff --git a/dev/integration_tests/ui/lib/commands.dart b/dev/integration_tests/ui/lib/commands.dart
index e15bbad..f5d758f 100644
--- a/dev/integration_tests/ui/lib/commands.dart
+++ b/dev/integration_tests/ui/lib/commands.dart
@@ -15,7 +15,7 @@
await WidgetsBinding.instance.reassembleApplication();
return log;
});
- runApp(MaterialApp(home: const Test()));
+ runApp(const MaterialApp(home: Test()));
}
class Test extends SingleChildRenderObjectWidget {
diff --git a/dev/manual_tests/lib/animated_icons.dart b/dev/manual_tests/lib/animated_icons.dart
index 718dba8..3cf6f10 100644
--- a/dev/manual_tests/lib/animated_icons.dart
+++ b/dev/manual_tests/lib/animated_icons.dart
@@ -7,9 +7,9 @@
class AnimatedIconsTestApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
- return MaterialApp(
+ return const MaterialApp(
title: 'Animated Icons Test',
- home: const Scaffold(
+ home: Scaffold(
body: IconsList(),
),
);
diff --git a/dev/manual_tests/lib/material_arc.dart b/dev/manual_tests/lib/material_arc.dart
index 06cdf9f..5b7fada 100644
--- a/dev/manual_tests/lib/material_arc.dart
+++ b/dev/manual_tests/lib/material_arc.dart
@@ -474,7 +474,7 @@
}
void main() {
- runApp(MaterialApp(
- home: const AnimationDemo(),
+ runApp(const MaterialApp(
+ home: AnimationDemo(),
));
}
diff --git a/examples/flutter_gallery/test/accessibility_test.dart b/examples/flutter_gallery/test/accessibility_test.dart
index 423469c..5668126 100644
--- a/examples/flutter_gallery/test/accessibility_test.dart
+++ b/examples/flutter_gallery/test/accessibility_test.dart
@@ -91,7 +91,7 @@
testWidgets('grid_list_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(MaterialApp(home: const GridListDemo()));
+ await tester.pumpWidget(const MaterialApp(home: GridListDemo()));
expect(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose();
});
@@ -105,21 +105,21 @@
testWidgets('leave_behind_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(MaterialApp(home: const LeaveBehindDemo()));
+ await tester.pumpWidget(const MaterialApp(home: LeaveBehindDemo()));
expect(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose();
});
testWidgets('list_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(MaterialApp(home: const ListDemo()));
+ await tester.pumpWidget(const MaterialApp(home: ListDemo()));
expect(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose();
});
testWidgets('menu_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(MaterialApp(home: const MenuDemo()));
+ await tester.pumpWidget(const MaterialApp(home: MenuDemo()));
expect(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose();
});
@@ -133,7 +133,7 @@
testWidgets('overscroll_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(MaterialApp(home: const OverscrollDemo()));
+ await tester.pumpWidget(const MaterialApp(home: OverscrollDemo()));
expect(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose();
});
@@ -161,7 +161,7 @@
testWidgets('reorderable_list_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(MaterialApp(home: const ReorderableListDemo()));
+ await tester.pumpWidget(const MaterialApp(home: ReorderableListDemo()));
expect(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose();
});
@@ -196,7 +196,7 @@
testWidgets('snack_bar_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(MaterialApp(home: const SnackBarDemo()));
+ await tester.pumpWidget(const MaterialApp(home: SnackBarDemo()));
expect(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose();
});
@@ -217,7 +217,7 @@
testWidgets('text_form_field_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(MaterialApp(home: const TextFormFieldDemo()));
+ await tester.pumpWidget(const MaterialApp(home: TextFormFieldDemo()));
expect(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose();
});
@@ -380,12 +380,12 @@
handle.dispose();
});
- testWidgets('overscroll_demo $themeName', (WidgetTester tester) async {
- final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(MaterialApp(theme: theme, home: const OverscrollDemo()));
- await expectLater(tester, meetsGuideline(textContrastGuideline));
- handle.dispose();
- });
+ testWidgets('overscroll_demo', (WidgetTester tester) async {
+ final SemanticsHandle handle = tester.ensureSemantics();
+ await tester.pumpWidget(const MaterialApp(home: OverscrollDemo()));
+ await expectLater(tester, meetsGuideline(textContrastGuideline));
+ handle.dispose();
+ });
testWidgets('page_selector_demo $themeName', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
diff --git a/examples/flutter_gallery/test/calculator/smoke_test.dart b/examples/flutter_gallery/test/calculator/smoke_test.dart
index 177ac3d..8f4b2e5 100644
--- a/examples/flutter_gallery/test/calculator/smoke_test.dart
+++ b/examples/flutter_gallery/test/calculator/smoke_test.dart
@@ -14,7 +14,7 @@
// We press the "1" and the "2" buttons and check that the display
// reads "12".
testWidgets('Flutter calculator app smoke test', (WidgetTester tester) async {
- await tester.pumpWidget(MaterialApp(home: const CalculatorDemo()));
+ await tester.pumpWidget(const MaterialApp(home: CalculatorDemo()));
final Finder oneButton = find.widgetWithText(InkResponse, '1');
expect(oneButton, findsOneWidget);
diff --git a/examples/flutter_gallery/test/demo/material/text_form_field_demo_test.dart b/examples/flutter_gallery/test/demo/material/text_form_field_demo_test.dart
index 8ca1a27..7a79303 100644
--- a/examples/flutter_gallery/test/demo/material/text_form_field_demo_test.dart
+++ b/examples/flutter_gallery/test/demo/material/text_form_field_demo_test.dart
@@ -8,7 +8,7 @@
void main() {
testWidgets('validates name field correctly', (WidgetTester tester) async {
- await tester.pumpWidget(MaterialApp(home: const TextFormFieldDemo()));
+ await tester.pumpWidget(const MaterialApp(home: TextFormFieldDemo()));
final Finder submitButton = find.widgetWithText(RaisedButton, 'SUBMIT');
expect(submitButton, findsOneWidget);
diff --git a/packages/flutter/lib/src/cupertino/app.dart b/packages/flutter/lib/src/cupertino/app.dart
index 1bb7d6a..362c043 100644
--- a/packages/flutter/lib/src/cupertino/app.dart
+++ b/packages/flutter/lib/src/cupertino/app.dart
@@ -8,7 +8,7 @@
import 'button.dart';
import 'colors.dart';
import 'icons.dart';
-import 'tab_view.dart';
+import 'route.dart';
// Based on specs from https://developer.apple.com/design/resources/ for
// iOS 12.
@@ -74,8 +74,9 @@
/// This class creates an instance of [WidgetsApp].
///
/// The boolean arguments, [routes], and [navigatorObservers], must not be null.
- CupertinoApp({ // can't be const because the asserts use methods on Map :-(
+ const CupertinoApp({
Key key,
+ this.navigatorKey,
this.home,
this.routes = const <String, WidgetBuilder>{},
this.initialRoute,
@@ -97,43 +98,6 @@
this.debugShowCheckedModeBanner = true,
}) : assert(routes != null),
assert(navigatorObservers != null),
- assert(
- home == null ||
- !routes.containsKey(Navigator.defaultRouteName),
- 'If the home property is specified, the routes table '
- 'cannot include an entry for "/", since it would be redundant.'
- ),
- assert(
- builder != null ||
- home != null ||
- routes.containsKey(Navigator.defaultRouteName) ||
- onGenerateRoute != null ||
- onUnknownRoute != null,
- 'Either the home property must be specified, '
- 'or the routes table must include an entry for "/", '
- 'or there must be on onGenerateRoute callback specified, '
- 'or there must be an onUnknownRoute callback specified, '
- 'or the builder property must be specified, '
- 'because otherwise there is nothing to fall back on if the '
- 'app is started with an intent that specifies an unknown route.'
- ),
- assert(
- (home != null ||
- routes.isNotEmpty ||
- onGenerateRoute != null ||
- onUnknownRoute != null)
- ||
- (builder != null &&
- initialRoute == null &&
- navigatorObservers.isEmpty),
- 'If no route is provided using '
- 'home, routes, onGenerateRoute, or onUnknownRoute, '
- 'a non-null callback for the builder property must be provided, '
- 'and the other navigator-related properties, '
- 'navigatorKey, initialRoute, and navigatorObservers, '
- 'must have their initial values '
- '(null, null, and the empty list, respectively).'
- ),
assert(title != null),
assert(showPerformanceOverlay != null),
assert(checkerboardRasterCacheImages != null),
@@ -142,31 +106,10 @@
assert(debugShowCheckedModeBanner != null),
super(key: key);
- /// The widget for the default route of the app ([Navigator.defaultRouteName],
- /// which is `/`).
- ///
- /// This is the route that is displayed first when the application is started
- /// normally, unless [initialRoute] is specified. It's also the route that's
- /// displayed if the [initialRoute] can't be displayed.
- ///
- /// To be able to directly call [MediaQuery.of], [Navigator.of], etc, in the
- /// code that sets the [home] argument in the constructor, you can use a
- /// [Builder] widget to get a [BuildContext].
- ///
- /// If [home] is specified, then [routes] must not include an entry for `/`,
- /// as [home] takes its place.
- ///
- /// The [Navigator] is only built if routes are provided (either via [home],
- /// [routes], [onGenerateRoute], or [onUnknownRoute]); if they are not,
- /// [builder] must not be null.
- ///
- /// The difference between using [home] and using [builder] is that the [home]
- /// subtree is inserted into the application below a [Navigator] (and thus
- /// below an [Overlay], which [Navigator] uses). With [home], therefore,
- /// dialog boxes will work automatically, the [routes] table will be used, and
- /// APIs such as [Navigator.push] and [Navigator.pop] will work as expected.
- /// In contrast, the widget returned from [builder] is inserted _above_ the
- /// [CupertinoApp]'s [Navigator] (if any).
+ /// {@macro flutter.widgets.widgetsApp.navigatorKey}
+ final GlobalKey<NavigatorState> navigatorKey;
+
+ /// {@macro flutter.widgets.widgetsApp.home}
final Widget home;
/// The application's top-level routing table.
@@ -176,81 +119,22 @@
/// [WidgetBuilder] is used to construct a [CupertinoPageRoute] that performs
/// an appropriate transition, including [Hero] animations, to the new route.
///
- /// If the app only has one page, then you can specify it using [home] instead.
- ///
- /// If [home] is specified, then it implies an entry in this table for the
- /// [Navigator.defaultRouteName] route (`/`), and it is an error to
- /// redundantly provide such a route in the [routes] table.
- ///
- /// If a route is requested that is not specified in this table (or by
- /// [home]), then the [onGenerateRoute] callback is called to build the page
- /// instead.
- ///
- /// The [Navigator] is only built if routes are provided (either via [home],
- /// [routes], [onGenerateRoute], or [onUnknownRoute]); if they are not,
- /// [builder] must not be null.
+ /// {@macro flutter.widgets.widgetsApp.routes}
final Map<String, WidgetBuilder> routes;
/// {@macro flutter.widgets.widgetsApp.initialRoute}
- ///
- /// The [Navigator] is only built if routes are provided (either via [home],
- /// [routes], [onGenerateRoute], or [onUnknownRoute]); if they are not,
- /// [initialRoute] must be null and [builder] must not be null.
- ///
- /// See also:
- ///
- /// * [Navigator.initialRoute], which is used to implement this property.
- /// * [Navigator.push], for pushing additional routes.
- /// * [Navigator.pop], for removing a route from the stack.
final String initialRoute;
/// {@macro flutter.widgets.widgetsApp.onGenerateRoute}
- ///
- /// This is used if [routes] does not contain the requested route.
- ///
- /// The [Navigator] is only built if routes are provided (either via [home],
- /// [routes], [onGenerateRoute], or [onUnknownRoute]); if they are not,
- /// [builder] must not be null.
final RouteFactory onGenerateRoute;
- /// Called when [onGenerateRoute] fails to generate a route, except for the
- /// [initialRoute].
- ///
/// {@macro flutter.widgets.widgetsApp.onUnknownRoute}
- ///
- /// The [Navigator] is only built if routes are provided (either via [home],
- /// [routes], [onGenerateRoute], or [onUnknownRoute]); if they are not,
- /// [builder] must not be null.
final RouteFactory onUnknownRoute;
/// {@macro flutter.widgets.widgetsApp.navigatorObservers}
- ///
- /// The [Navigator] is only built if routes are provided (either via [home],
- /// [routes], [onGenerateRoute], or [onUnknownRoute]); if they are not,
- /// [navigatorObservers] must be the empty list and [builder] must not be null.
final List<NavigatorObserver> navigatorObservers;
/// {@macro flutter.widgets.widgetsApp.builder}
- ///
- /// If no routes are provided using [home], [routes], [onGenerateRoute], or
- /// [onUnknownRoute], the `child` will be null, and it is the responsibility
- /// of the [builder] to provide the application's routing machinery.
- ///
- /// If routes _are_ provided using one or more of those properties, then
- /// `child` is not null, and the returned value should include the `child` in
- /// the widget subtree; if it does not, then the application will have no
- /// navigator and the [navigatorKey], [home], [routes], [onGenerateRoute],
- /// [onUnknownRoute], [initialRoute], and [navigatorObservers] properties will
- /// have no effect.
- ///
- /// If [builder] is null, it is as if a builder was specified that returned
- /// the `child` directly. If it is null, routes must be provided using one of
- /// the other properties listed above.
- ///
- /// Unless a [Navigator] is provided, either implicitly from [builder] being
- /// null, or by a [builder] including its `child` argument, or by a [builder]
- /// explicitly providing a [Navigator] of its own, widgets and APIs such as
- /// [Hero], [Navigator.push] and [Navigator.pop], will not function.
final TransitionBuilder builder;
/// {@macro flutter.widgets.widgetsApp.title}
@@ -304,6 +188,12 @@
@override
_CupertinoAppState createState() => _CupertinoAppState();
+
+ /// The [HeroController] used for Cupertino page transitions.
+ ///
+ /// Used by [CupertinoTabView] and [CupertinoApp].
+ static HeroController createCupertinoHeroController() =>
+ HeroController(); // Linear tweening.
}
class _AlwaysCupertinoScrollBehavior extends ScrollBehavior {
@@ -320,51 +210,39 @@
}
class _CupertinoAppState extends State<CupertinoApp> {
+ HeroController _heroController;
@override
void initState() {
super.initState();
+ _heroController = CupertinoApp.createCupertinoHeroController();
_updateNavigator();
}
@override
void didUpdateWidget(CupertinoApp oldWidget) {
super.didUpdateWidget(oldWidget);
+ if (widget.navigatorKey != oldWidget.navigatorKey) {
+ // If the Navigator changes, we have to create a new observer, because the
+ // old Navigator won't be disposed (and thus won't unregister with its
+ // observers) until after the new one has been created (because the
+ // Navigator has a GlobalKey).
+ _heroController = CupertinoApp.createCupertinoHeroController();
+ }
_updateNavigator();
}
- bool _haveNavigator;
- void _updateNavigator() {
- _haveNavigator = widget.home != null ||
- widget.routes.isNotEmpty ||
- widget.onGenerateRoute != null ||
- widget.onUnknownRoute != null;
- }
+ List<NavigatorObserver> _navigatorObservers;
- Widget defaultBuilder(BuildContext context, Widget child) {
- // The `child` coming back out from WidgetsApp will always be null since
- // we never passed in anything for it to create a Navigator inside
- // WidgetsApp.
- assert(child == null);
- if (_haveNavigator) {
- // Reuse CupertinoTabView which creates a routing Navigator for us.
- final Widget navigator = CupertinoTabView(
- builder: widget.home != null
- ? (BuildContext context) => widget.home
- : null,
- routes: widget.routes,
- onGenerateRoute: widget.onGenerateRoute,
- onUnknownRoute: widget.onUnknownRoute,
- navigatorObservers: widget.navigatorObservers,
- );
- if (widget.builder != null) {
- return widget.builder(context, navigator);
- } else {
- return navigator;
- }
+ void _updateNavigator() {
+ if (widget.home != null ||
+ widget.routes.isNotEmpty ||
+ widget.onGenerateRoute != null ||
+ widget.onUnknownRoute != null) {
+ _navigatorObservers = List<NavigatorObserver>.from(widget.navigatorObservers)
+ ..add(_heroController);
} else {
- // We asserted that child is null above.
- return widget.builder(context, null);
+ _navigatorObservers = null;
}
}
@@ -374,10 +252,18 @@
behavior: _AlwaysCupertinoScrollBehavior(),
child: WidgetsApp(
key: GlobalObjectKey(this),
- // We're passing in a builder and nothing else that the WidgetsApp uses
- // to build its own Navigator because we're building a Navigator with
- // routes in this class.
- builder: defaultBuilder,
+ navigatorKey: widget.navigatorKey,
+ navigatorObservers: _navigatorObservers,
+ // TODO(dnfield): when https://github.com/dart-lang/sdk/issues/34572 is resolved
+ // this can use type arguments again
+ pageRouteBuilder: (RouteSettings settings, WidgetBuilder builder) =>
+ CupertinoPageRoute<dynamic>(settings: settings, builder: builder),
+ home: widget.home,
+ routes: widget.routes,
+ initialRoute: widget.initialRoute,
+ onGenerateRoute: widget.onGenerateRoute,
+ onUnknownRoute: widget.onUnknownRoute,
+ builder: widget.builder,
title: widget.title,
onGenerateTitle: widget.onGenerateTitle,
textStyle: _kDefaultTextStyle,
diff --git a/packages/flutter/lib/src/cupertino/tab_view.dart b/packages/flutter/lib/src/cupertino/tab_view.dart
index d27a86c..08bb615 100644
--- a/packages/flutter/lib/src/cupertino/tab_view.dart
+++ b/packages/flutter/lib/src/cupertino/tab_view.dart
@@ -4,6 +4,7 @@
import 'package:flutter/widgets.dart';
+import 'app.dart' show CupertinoApp;
import 'route.dart';
/// A single tab view with its own [Navigator] state and history.
@@ -114,7 +115,7 @@
@override
void initState() {
super.initState();
- _heroController = HeroController(); // Linear tweening.
+ _heroController = CupertinoApp.createCupertinoHeroController();
_updateObservers();
}
diff --git a/packages/flutter/lib/src/material/app.dart b/packages/flutter/lib/src/material/app.dart
index a47f803..e1b6274 100644
--- a/packages/flutter/lib/src/material/app.dart
+++ b/packages/flutter/lib/src/material/app.dart
@@ -79,7 +79,7 @@
/// This class creates an instance of [WidgetsApp].
///
/// The boolean arguments, [routes], and [navigatorObservers], must not be null.
- MaterialApp({ // can't be const because the asserts use methods on Map :-(
+ const MaterialApp({
Key key,
this.navigatorKey,
this.home,
@@ -105,44 +105,6 @@
this.debugShowCheckedModeBanner = true,
}) : assert(routes != null),
assert(navigatorObservers != null),
- assert(
- home == null ||
- !routes.containsKey(Navigator.defaultRouteName),
- 'If the home property is specified, the routes table '
- 'cannot include an entry for "/", since it would be redundant.'
- ),
- assert(
- builder != null ||
- home != null ||
- routes.containsKey(Navigator.defaultRouteName) ||
- onGenerateRoute != null ||
- onUnknownRoute != null,
- 'Either the home property must be specified, '
- 'or the routes table must include an entry for "/", '
- 'or there must be on onGenerateRoute callback specified, '
- 'or there must be an onUnknownRoute callback specified, '
- 'or the builder property must be specified, '
- 'because otherwise there is nothing to fall back on if the '
- 'app is started with an intent that specifies an unknown route.'
- ),
- assert(
- (home != null ||
- routes.isNotEmpty ||
- onGenerateRoute != null ||
- onUnknownRoute != null)
- ||
- (builder != null &&
- navigatorKey == null &&
- initialRoute == null &&
- navigatorObservers.isEmpty),
- 'If no route is provided using '
- 'home, routes, onGenerateRoute, or onUnknownRoute, '
- 'a non-null callback for the builder property must be provided, '
- 'and the other navigator-related properties, '
- 'navigatorKey, initialRoute, and navigatorObservers, '
- 'must have their initial values '
- '(null, null, and the empty list, respectively).'
- ),
assert(title != null),
assert(debugShowMaterialGrid != null),
assert(showPerformanceOverlay != null),
@@ -152,48 +114,10 @@
assert(debugShowCheckedModeBanner != null),
super(key: key);
- /// A key to use when building the [Navigator].
- ///
- /// If a [navigatorKey] is specified, the [Navigator] can be directly
- /// manipulated without first obtaining it from a [BuildContext] via
- /// [Navigator.of]: from the [navigatorKey], use the [GlobalKey.currentState]
- /// getter.
- ///
- /// If this is changed, a new [Navigator] will be created, losing all the
- /// application state in the process; in that case, the [navigatorObservers]
- /// must also be changed, since the previous observers will be attached to the
- /// previous navigator.
- ///
- /// The [Navigator] is only built if routes are provided (either via [home],
- /// [routes], [onGenerateRoute], or [onUnknownRoute]); if they are not,
- /// [navigatorKey] must be null and [builder] must not be null.
+ /// {@macro flutter.widgets.widgetsApp.navigatorKey}
final GlobalKey<NavigatorState> navigatorKey;
- /// The widget for the default route of the app ([Navigator.defaultRouteName],
- /// which is `/`).
- ///
- /// This is the route that is displayed first when the application is started
- /// normally, unless [initialRoute] is specified. It's also the route that's
- /// displayed if the [initialRoute] can't be displayed.
- ///
- /// To be able to directly call [Theme.of], [MediaQuery.of], etc, in the code
- /// that sets the [home] argument in the constructor, you can use a [Builder]
- /// widget to get a [BuildContext].
- ///
- /// If [home] is specified, then [routes] must not include an entry for `/`,
- /// as [home] takes its place.
- ///
- /// The [Navigator] is only built if routes are provided (either via [home],
- /// [routes], [onGenerateRoute], or [onUnknownRoute]); if they are not,
- /// [builder] must not be null.
- ///
- /// The difference between using [home] and using [builder] is that the [home]
- /// subtree is inserted into the application below a [Navigator] (and thus
- /// below an [Overlay], which [Navigator] uses). With [home], therefore,
- /// dialog boxes will work automatically, [Tooltip]s will work, the [routes]
- /// table will be used, and APIs such as [Navigator.push] and [Navigator.pop]
- /// will work as expected. In contrast, the widget returned from [builder] is
- /// inserted _above_ the [MaterialApp]'s [Navigator] (if any).
+ /// {@macro flutter.widgets.widgetsApp.home}
final Widget home;
/// The application's top-level routing table.
@@ -203,82 +127,25 @@
/// [WidgetBuilder] is used to construct a [MaterialPageRoute] that performs
/// an appropriate transition, including [Hero] animations, to the new route.
///
- /// If the app only has one page, then you can specify it using [home] instead.
- ///
- /// If [home] is specified, then it implies an entry in this table for the
- /// [Navigator.defaultRouteName] route (`/`), and it is an error to
- /// redundantly provide such a route in the [routes] table.
- ///
- /// If a route is requested that is not specified in this table (or by
- /// [home]), then the [onGenerateRoute] callback is called to build the page
- /// instead.
- ///
- /// The [Navigator] is only built if routes are provided (either via [home],
- /// [routes], [onGenerateRoute], or [onUnknownRoute]); if they are not,
- /// [builder] must not be null.
+ /// {@macro flutter.widgets.widgetsApp.routes}
final Map<String, WidgetBuilder> routes;
/// {@macro flutter.widgets.widgetsApp.initialRoute}
- ///
- /// The [Navigator] is only built if routes are provided (either via [home],
- /// [routes], [onGenerateRoute], or [onUnknownRoute]); if they are not,
- /// [initialRoute] must be null and [builder] must not be null.
- ///
- /// See also:
- ///
- /// * [Navigator.initialRoute], which is used to implement this property.
- /// * [Navigator.push], for pushing additional routes.
- /// * [Navigator.pop], for removing a route from the stack.
final String initialRoute;
/// {@macro flutter.widgets.widgetsApp.onGenerateRoute}
- ///
- /// This is used if [routes] does not contain the requested route.
- ///
- /// The [Navigator] is only built if routes are provided (either via [home],
- /// [routes], [onGenerateRoute], or [onUnknownRoute]); if they are not,
- /// [builder] must not be null.
final RouteFactory onGenerateRoute;
- /// Called when [onGenerateRoute] fails to generate a route, except for the
- /// [initialRoute].
- ///
/// {@macro flutter.widgets.widgetsApp.onUnknownRoute}
- ///
- /// The [Navigator] is only built if routes are provided (either via [home],
- /// [routes], [onGenerateRoute], or [onUnknownRoute]); if they are not,
- /// [builder] must not be null.
final RouteFactory onUnknownRoute;
/// {@macro flutter.widgets.widgetsApp.navigatorObservers}
- ///
- /// The [Navigator] is only built if routes are provided (either via [home],
- /// [routes], [onGenerateRoute], or [onUnknownRoute]); if they are not,
- /// [navigatorObservers] must be the empty list and [builder] must not be null.
final List<NavigatorObserver> navigatorObservers;
/// {@macro flutter.widgets.widgetsApp.builder}
///
- /// If no routes are provided using [home], [routes], [onGenerateRoute], or
- /// [onUnknownRoute], the `child` will be null, and it is the responsibility
- /// of the [builder] to provide the application's routing machinery.
- ///
- /// If routes _are_ provided using one or more of those properties, then
- /// `child` is not null, and the returned value should include the `child` in
- /// the widget subtree; if it does not, then the application will have no
- /// navigator and the [navigatorKey], [home], [routes], [onGenerateRoute],
- /// [onUnknownRoute], [initialRoute], and [navigatorObservers] properties will
- /// have no effect.
- ///
- /// If [builder] is null, it is as if a builder was specified that returned
- /// the `child` directly. If it is null, routes must be provided using one of
- /// the other properties listed above.
- ///
- /// Unless a [Navigator] is provided, either implicitly from [builder] being
- /// null, or by a [builder] including its `child` argument, or by a [builder]
- /// explicitly providing a [Navigator] of its own, features such as
- /// [showDialog] and [showMenu], widgets such as [Tooltip], [PopupMenuButton],
- /// or [Hero], and APIs such as [Navigator.push] and [Navigator.pop], will not
+ /// Material specific features such as [showDialog] and [showMenu], and widgets
+ /// such as [Tooltip], [PopupMenuButton], also require a [Navigator] to properly
/// function.
final TransitionBuilder builder;
@@ -472,73 +339,24 @@
_updateNavigator();
}
- bool _haveNavigator;
List<NavigatorObserver> _navigatorObservers;
void _updateNavigator() {
- _haveNavigator = widget.home != null ||
- widget.routes.isNotEmpty ||
- widget.onGenerateRoute != null ||
- widget.onUnknownRoute != null;
- _navigatorObservers = List<NavigatorObserver>.from(widget.navigatorObservers)
- ..add(_heroController);
+ if (widget.home != null ||
+ widget.routes.isNotEmpty ||
+ widget.onGenerateRoute != null ||
+ widget.onUnknownRoute != null) {
+ _navigatorObservers = List<NavigatorObserver>.from(widget.navigatorObservers)
+ ..add(_heroController);
+ } else {
+ _navigatorObservers = null;
+ }
}
RectTween _createRectTween(Rect begin, Rect end) {
return MaterialRectArcTween(begin: begin, end: end);
}
- Route<dynamic> _onGenerateRoute(RouteSettings settings) {
- final String name = settings.name;
- WidgetBuilder builder;
- if (name == Navigator.defaultRouteName && widget.home != null) {
- builder = (BuildContext context) => widget.home;
- } else {
- builder = widget.routes[name];
- }
- if (builder != null) {
- return MaterialPageRoute<dynamic>(
- builder: builder,
- settings: settings,
- );
- }
- if (widget.onGenerateRoute != null)
- return widget.onGenerateRoute(settings);
- return null;
- }
-
- Route<dynamic> _onUnknownRoute(RouteSettings settings) {
- assert(() {
- if (widget.onUnknownRoute == null) {
- throw FlutterError(
- 'Could not find a generator for route $settings in the $runtimeType.\n'
- 'Generators for routes are searched for in the following order:\n'
- ' 1. For the "/" route, the "home" property, if non-null, is used.\n'
- ' 2. Otherwise, the "routes" table is used, if it has an entry for '
- 'the route.\n'
- ' 3. Otherwise, onGenerateRoute is called. It should return a '
- 'non-null value for any valid route not handled by "home" and "routes".\n'
- ' 4. Finally if all else fails onUnknownRoute is called.\n'
- 'Unfortunately, onUnknownRoute was not set.'
- );
- }
- return true;
- }());
- final Route<dynamic> result = widget.onUnknownRoute(settings);
- assert(() {
- if (result == null) {
- throw FlutterError(
- 'The onUnknownRoute callback returned null.\n'
- 'When the $runtimeType requested the route $settings from its '
- 'onUnknownRoute callback, the callback returned null. Such callbacks '
- 'must never return null.'
- );
- }
- return true;
- }());
- return result;
- }
-
// Combine the Localizations for Material with the ones contributed
// by the localizationsDelegates parameter, if any. Only the first delegate
// of a particular LocalizationsDelegate.type is loaded so the
@@ -559,10 +377,16 @@
child: WidgetsApp(
key: GlobalObjectKey(this),
navigatorKey: widget.navigatorKey,
- navigatorObservers: _haveNavigator ? _navigatorObservers : null,
+ navigatorObservers: _navigatorObservers,
+ // TODO(dnfield): when https://github.com/dart-lang/sdk/issues/34572 is resolved
+ // this can use type arguments again
+ pageRouteBuilder: (RouteSettings settings, WidgetBuilder builder) =>
+ MaterialPageRoute<dynamic>(settings: settings, builder: builder),
+ home: widget.home,
+ routes: widget.routes,
initialRoute: widget.initialRoute,
- onGenerateRoute: _haveNavigator ? _onGenerateRoute : null,
- onUnknownRoute: _haveNavigator ? _onUnknownRoute : null,
+ onGenerateRoute: widget.onGenerateRoute,
+ onUnknownRoute: widget.onUnknownRoute,
builder: widget.builder,
title: widget.title,
onGenerateTitle: widget.onGenerateTitle,
diff --git a/packages/flutter/lib/src/widgets/app.dart b/packages/flutter/lib/src/widgets/app.dart
index e8c95ea..a6db3e3 100644
--- a/packages/flutter/lib/src/widgets/app.dart
+++ b/packages/flutter/lib/src/widgets/app.dart
@@ -14,6 +14,7 @@
import 'localizations.dart';
import 'media_query.dart';
import 'navigator.dart';
+import 'pages.dart';
import 'performance_overlay.dart';
import 'semantics_debugger.dart';
import 'text.dart';
@@ -43,6 +44,13 @@
/// This function must not return null.
typedef GenerateAppTitle = String Function(BuildContext context);
+/// The signature of [WidgetsApp.pageRouteBuilder].
+///
+/// Creates a [PageRoute] using the given [RouteSettings] and [WidgetBuilder].
+// TODO(dnfield): when https://github.com/dart-lang/sdk/issues/34572 is resolved
+// this can use type arguments again
+typedef PageRouteFactory = PageRoute<dynamic> Function(RouteSettings settings, WidgetBuilder builder);
+
/// A convenience class that wraps a number of widgets that are commonly
/// required for an application.
///
@@ -58,8 +66,10 @@
///
/// The boolean arguments, [color], and [navigatorObservers] must not be null.
///
- /// If the [builder] is null, the [onGenerateRoute] argument is required, and
- /// corresponds to [Navigator.onGenerateRoute]. If the [builder] is non-null
+ /// If the [builder] is null, the [onGenerateRoute] and [pageRouteBuilder]
+ /// arguments are required. The [onGenerateRoute] parameter corresponds to
+ /// [Navigator.onGenerateRoute], and [pageRouteBuilder] will create a [PageRoute]
+ /// that wraps newly built routes. If the [builder] is non-null
/// and the [onGenerateRoute] argument is null, then the [builder] will not be
/// provided with a [Navigator]. If [onGenerateRoute] is not provided,
/// [navigatorKey], [onUnknownRoute], [navigatorObservers], and [initialRoute]
@@ -74,6 +84,9 @@
this.onUnknownRoute,
this.navigatorObservers = const <NavigatorObserver>[],
this.initialRoute,
+ this.pageRouteBuilder,
+ this.home,
+ this.routes = const <String, WidgetBuilder>{},
this.builder,
this.title = '',
this.onGenerateTitle,
@@ -91,11 +104,49 @@
this.debugShowCheckedModeBanner = true,
this.inspectorSelectButtonBuilder,
}) : assert(navigatorObservers != null),
- assert(onGenerateRoute != null || navigatorKey == null),
- assert(onGenerateRoute != null || onUnknownRoute == null),
- assert(onGenerateRoute != null || navigatorObservers == const <NavigatorObserver>[]),
- assert(onGenerateRoute != null || initialRoute == null),
- assert(onGenerateRoute != null || builder != null),
+ assert(routes != null),
+ assert(
+ home == null ||
+ !routes.containsKey(Navigator.defaultRouteName),
+ 'If the home property is specified, the routes table '
+ 'cannot include an entry for "/", since it would be redundant.'
+ ),
+ assert(
+ builder != null ||
+ home != null ||
+ routes.containsKey(Navigator.defaultRouteName) ||
+ onGenerateRoute != null ||
+ onUnknownRoute != null,
+ 'Either the home property must be specified, '
+ 'or the routes table must include an entry for "/", '
+ 'or there must be on onGenerateRoute callback specified, '
+ 'or there must be an onUnknownRoute callback specified, '
+ 'or the builder property must be specified, '
+ 'because otherwise there is nothing to fall back on if the '
+ 'app is started with an intent that specifies an unknown route.'
+ ),
+ assert(
+ (home != null ||
+ routes.isNotEmpty ||
+ onGenerateRoute != null ||
+ onUnknownRoute != null)
+ ||
+ (builder != null &&
+ navigatorKey == null &&
+ initialRoute == null &&
+ navigatorObservers.isEmpty),
+ 'If no route is provided using '
+ 'home, routes, onGenerateRoute, or onUnknownRoute, '
+ 'a non-null callback for the builder property must be provided, '
+ 'and the other navigator-related properties, '
+ 'navigatorKey, initialRoute, and navigatorObservers, '
+ 'must have their initial values '
+ '(null, null, and the empty list, respectively).'
+ ),
+ assert(onGenerateRoute != null || pageRouteBuilder != null,
+ 'If onGenerateRoute is not provided, the pageRouteBuilder must be specified '
+ 'so that the default handler will know what kind of PageRoute transition '
+ 'bo build.'),
assert(title != null),
assert(color != null),
assert(supportedLocales != null && supportedLocales.isNotEmpty),
@@ -107,6 +158,7 @@
assert(debugShowWidgetInspector != null),
super(key: key);
+ /// {@template flutter.widgets.widgetsApp.navigatorKey}
/// A key to use when building the [Navigator].
///
/// If a [navigatorKey] is specified, the [Navigator] can be directly
@@ -121,6 +173,7 @@
///
/// The [Navigator] is only built if [onGenerateRoute] is not null; if it is
/// null, [navigatorKey] must also be null.
+ /// {@endTemplate}
final GlobalKey<NavigatorState> navigatorKey;
/// {@template flutter.widgets.widgetsApp.onGenerateRoute}
@@ -134,25 +187,103 @@
/// During normal app operation, the [onGenerateRoute] callback will only be
/// applied to route names pushed by the application, and so should never
/// return null.
+ ///
+ /// This is used if [routes] does not contain the requested route.
+ ///
+ /// The [Navigator] is only built if routes are provided (either via [home],
+ /// [routes], [onGenerateRoute], or [onUnknownRoute]); if they are not,
+ /// [builder] must not be null.
/// {@endtemplate}
///
- /// The [Navigator] is only built if [onGenerateRoute] is not null. If
- /// [onGenerateRoute] is null, the [builder] must be non-null.
+ /// If this property is not set, either the [routes] or [home] properties must
+ /// be set, and the [pageRouteBuilder] must also be set so that the
+ /// default handler will know what routes and [PageRoute]s to build.
final RouteFactory onGenerateRoute;
- /// Called when [onGenerateRoute] fails to generate a route.
+ /// The [PageRoute] generator callback used when the app is navigated to a
+ /// named route.
///
+ /// This callback can be used, for example, to specify that a [MaterialPageRoute]
+ /// or a [CupertinoPageRoute] should be used for building page transitions.
+ final PageRouteFactory pageRouteBuilder;
+
+ /// {@template flutter.widgets.widgetsApp.home}
+ /// The widget for the default route of the app ([Navigator.defaultRouteName],
+ /// which is `/`).
+ ///
+ /// This is the route that is displayed first when the application is started
+ /// normally, unless [initialRoute] is specified. It's also the route that's
+ /// displayed if the [initialRoute] can't be displayed.
+ ///
+ /// To be able to directly call [Theme.of], [MediaQuery.of], etc, in the code
+ /// that sets the [home] argument in the constructor, you can use a [Builder]
+ /// widget to get a [BuildContext].
+ ///
+ /// If [home] is specified, then [routes] must not include an entry for `/`,
+ /// as [home] takes its place.
+ ///
+ /// The [Navigator] is only built if routes are provided (either via [home],
+ /// [routes], [onGenerateRoute], or [onUnknownRoute]); if they are not,
+ /// [builder] must not be null.
+ ///
+ /// The difference between using [home] and using [builder] is that the [home]
+ /// subtree is inserted into the application below a [Navigator] (and thus
+ /// below an [Overlay], which [Navigator] uses). With [home], therefore,
+ /// dialog boxes will work automatically, the [routes] table will be used, and
+ /// APIs such as [Navigator.push] and [Navigator.pop] will work as expected.
+ /// In contrast, the widget returned from [builder] is inserted _above_ the
+ /// app's [Navigator] (if any).
+ /// {@endTemplate}
+ ///
+ /// If this property is set, the [pageRouteBuilder] property must also be set
+ /// so that the default route handler will know what kind of [PageRoute]s to
+ /// build.
+ final Widget home;
+
+ /// The application's top-level routing table.
+ ///
+ /// When a named route is pushed with [Navigator.pushNamed], the route name is
+ /// looked up in this map. If the name is present, the associated
+ /// [WidgetBuilder] is used to construct a [PageRoute] specified by
+ /// [pageRouteBuilder] to perform an appropriate transition, including [Hero]
+ /// animations, to the new route.
+ ///
+ /// {@template flutter.widgets.widgetsApp.routes}
+ /// If the app only has one page, then you can specify it using [home] instead.
+ ///
+ /// If [home] is specified, then it implies an entry in this table for the
+ /// [Navigator.defaultRouteName] route (`/`), and it is an error to
+ /// redundantly provide such a route in the [routes] table.
+ ///
+ /// If a route is requested that is not specified in this table (or by
+ /// [home]), then the [onGenerateRoute] callback is called to build the page
+ /// instead.
+ ///
+ /// The [Navigator] is only built if routes are provided (either via [home],
+ /// [routes], [onGenerateRoute], or [onUnknownRoute]); if they are not,
+ /// [builder] must not be null.
+ /// {@endTemplate}
+ ///
+ /// If the routes map is not empty, the [pageRouteBuilder] property must be set
+ /// so that the default route handler will know what kind of [PageRoute]s to
+ /// build.
+ final Map<String, WidgetBuilder> routes;
+
/// {@template flutter.widgets.widgetsApp.onUnknownRoute}
+ /// Called when [onGenerateRoute] fails to generate a route, except for the
+ /// [initialRoute].
+ ///
/// This callback is typically used for error handling. For example, this
/// callback might always generate a "not found" page that describes the route
/// that wasn't found.
///
/// Unknown routes can arise either from errors in the app or from external
/// requests to push routes, such as from Android intents.
- /// {@endtemplate}
///
- /// The [Navigator] is only built if [onGenerateRoute] is not null; if it is
- /// null, [onUnknownRoute] must also be null.
+ /// The [Navigator] is only built if routes are provided (either via [home],
+ /// [routes], [onGenerateRoute], or [onUnknownRoute]); if they are not,
+ /// [builder] must not be null.
+ /// {@endtemplate}
final RouteFactory onUnknownRoute;
/// {@template flutter.widgets.widgetsApp.initialRoute}
@@ -170,16 +301,16 @@
/// [initialRoute] is ignored and [Navigator.defaultRouteName] is used instead
/// (`/`). This can happen if the app is started with an intent that specifies
/// a non-existent route.
- /// {@endtemplate}
- ///
- /// The [Navigator] is only built if [onGenerateRoute] is not null; if it is
- /// null, [initialRoute] must also be null.
+ /// The [Navigator] is only built if routes are provided (either via [home],
+ /// [routes], [onGenerateRoute], or [onUnknownRoute]); if they are not,
+ /// [initialRoute] must be null and [builder] must not be null.
///
/// See also:
///
/// * [Navigator.initialRoute], which is used to implement this property.
/// * [Navigator.push], for pushing additional routes.
/// * [Navigator.pop], for removing a route from the stack.
+ /// {@endtemplate}
final String initialRoute;
/// {@template flutter.widgets.widgetsApp.navigatorObservers}
@@ -187,11 +318,11 @@
///
/// This list must be replaced by a list of newly-created observers if the
/// [navigatorKey] is changed.
- /// {@endtemplate}
///
- /// The [Navigator] is only built if [onGenerateRoute] is not null; if it is
- /// null, [navigatorObservers] must be left to its default value, the empty
- /// list.
+ /// The [Navigator] is only built if routes are provided (either via [home],
+ /// [routes], [onGenerateRoute], or [onUnknownRoute]); if they are not,
+ /// [navigatorObservers] must be the empty list and [builder] must not be null.
+ /// {@endtemplate}
final List<NavigatorObserver> navigatorObservers;
/// {@template flutter.widgets.widgetsApp.builder}
@@ -214,21 +345,27 @@
///
/// The [builder] callback is passed two arguments, the [BuildContext] (as
/// `context`) and a [Navigator] widget (as `child`).
- /// {@endtemplate}
///
- /// If [onGenerateRoute] is null, the `child` will be null, and it is the
- /// responsibility of the [builder] to provide the application's routing
- /// machinery.
+ /// If no routes are provided using [home], [routes], [onGenerateRoute], or
+ /// [onUnknownRoute], the `child` will be null, and it is the responsibility
+ /// of the [builder] to provide the application's routing machinery.
///
- /// If [onGenerateRoute] is not null, then `child` is not null, and the
- /// returned value should include the `child` in the widget subtree; if it
- /// does not, then the application will have no navigator and the
- /// [navigatorKey], [onGenerateRoute], [onUnknownRoute], [initialRoute], and
- /// [navigatorObservers] properties will have no effect.
+ /// If routes _are_ provided using one or more of those properties, then
+ /// `child` is not null, and the returned value should include the `child` in
+ /// the widget subtree; if it does not, then the application will have no
+ /// navigator and the [navigatorKey], [home], [routes], [onGenerateRoute],
+ /// [onUnknownRoute], [initialRoute], and [navigatorObservers] properties will
+ /// have no effect.
///
/// If [builder] is null, it is as if a builder was specified that returned
- /// the `child` directly. At least one of either [onGenerateRoute] or
- /// [builder] must be non-null.
+ /// the `child` directly. If it is null, routes must be provided using one of
+ /// the other properties listed above.
+ ///
+ /// Unless a [Navigator] is provided, either implicitly from [builder] being
+ /// null, or by a [builder] including its `child` argument, or by a [builder]
+ /// explicitly providing a [Navigator] of its own, widgets and APIs such as
+ /// [Hero], [Navigator.push] and [Navigator.pop], will not function.
+ /// {@endtemplate}
final TransitionBuilder builder;
/// {@template flutter.widgets.widgetsApp.title}
@@ -455,11 +592,64 @@
GlobalKey<NavigatorState> _navigator;
void _updateNavigator() {
- if (widget.onGenerateRoute == null) {
- _navigator = null;
+ _navigator = widget.navigatorKey ?? GlobalObjectKey<NavigatorState>(this);
+ }
+
+ Route<dynamic> _onGenerateRoute(RouteSettings settings) {
+ final String name = settings.name;
+ WidgetBuilder builder;
+ if (name == Navigator.defaultRouteName && widget.home != null) {
+ builder = (BuildContext context) => widget.home;
} else {
- _navigator = widget.navigatorKey ?? GlobalObjectKey<NavigatorState>(this);
+ builder = widget.routes[name];
}
+ if (builder != null) {
+ assert(widget.pageRouteBuilder != null,
+ 'The default onGenerateRoute handler for WidgetsApp must have a '
+ 'pageRouteBuilder set if the home or routes properties are set.');
+ final Route<dynamic> route = widget.pageRouteBuilder(
+ settings,
+ builder,
+ );
+ assert(route != null,
+ 'The pageRouteBuilder for WidgetsApp must return a valid non-null Route.');
+ return route;
+ }
+ if (widget.onGenerateRoute != null)
+ return widget.onGenerateRoute(settings);
+ return null;
+ }
+
+ Route<dynamic> _onUnknownRoute(RouteSettings settings) {
+ assert(() {
+ if (widget.onUnknownRoute == null) {
+ throw FlutterError(
+ 'Could not find a generator for route $settings in the $runtimeType.\n'
+ 'Generators for routes are searched for in the following order:\n'
+ ' 1. For the "/" route, the "home" property, if non-null, is used.\n'
+ ' 2. Otherwise, the "routes" table is used, if it has an entry for '
+ 'the route.\n'
+ ' 3. Otherwise, onGenerateRoute is called. It should return a '
+ 'non-null value for any valid route not handled by "home" and "routes".\n'
+ ' 4. Finally if all else fails onUnknownRoute is called.\n'
+ 'Unfortunately, onUnknownRoute was not set.'
+ );
+ }
+ return true;
+ }());
+ final Route<dynamic> result = widget.onUnknownRoute(settings);
+ assert(() {
+ if (result == null) {
+ throw FlutterError(
+ 'The onUnknownRoute callback returned null.\n'
+ 'When the $runtimeType requested the route $settings from its '
+ 'onUnknownRoute callback, the callback returned null. Such callbacks '
+ 'must never return null.'
+ );
+ }
+ return true;
+ }());
+ return result;
}
// On Android: the user has pressed the back button.
@@ -566,9 +756,14 @@
if (_navigator != null) {
navigator = Navigator(
key: _navigator,
- initialRoute: widget.initialRoute ?? ui.window.defaultRouteName,
- onGenerateRoute: widget.onGenerateRoute,
- onUnknownRoute: widget.onUnknownRoute,
+ // If ui.window.defaultRouteName isn't '/', we should assume it was set
+ // intentionally via `setInitialRoute`, and should override whatever
+ // is in [widget.initialRoute].
+ initialRoute: ui.window.defaultRouteName != Navigator.defaultRouteName
+ ? ui.window.defaultRouteName
+ : widget.initialRoute ?? ui.window.defaultRouteName,
+ onGenerateRoute: _onGenerateRoute,
+ onUnknownRoute: _onUnknownRoute,
observers: widget.navigatorObservers,
);
}
diff --git a/packages/flutter/test/cupertino/dialog_test.dart b/packages/flutter/test/cupertino/dialog_test.dart
index 65133e9..29a3bcc 100644
--- a/packages/flutter/test/cupertino/dialog_test.dart
+++ b/packages/flutter/test/cupertino/dialog_test.dart
@@ -66,7 +66,7 @@
testWidgets('Has semantic annotations', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester);
- await tester.pumpWidget(MaterialApp(home: const Material(
+ await tester.pumpWidget(const MaterialApp(home: Material(
child: CupertinoAlertDialog(
title: Text('The Title'),
content: Text('Content'),
diff --git a/packages/flutter/test/cupertino/nav_bar_test.dart b/packages/flutter/test/cupertino/nav_bar_test.dart
index 8ca3f6c..3ccadc0 100644
--- a/packages/flutter/test/cupertino/nav_bar_test.dart
+++ b/packages/flutter/test/cupertino/nav_bar_test.dart
@@ -16,8 +16,8 @@
void main() {
testWidgets('Middle still in center with asymmetrical actions', (WidgetTester tester) async {
await tester.pumpWidget(
- CupertinoApp(
- home: const CupertinoNavigationBar(
+ const CupertinoApp(
+ home: CupertinoNavigationBar(
leading: CupertinoButton(child: Text('Something'), onPressed: null,),
middle: Text('Title'),
),
@@ -30,8 +30,8 @@
testWidgets('Middle still in center with back button', (WidgetTester tester) async {
await tester.pumpWidget(
- CupertinoApp(
- home: const CupertinoNavigationBar(
+ const CupertinoApp(
+ home: CupertinoNavigationBar(
middle: Text('Title'),
),
),
@@ -54,8 +54,8 @@
testWidgets('Opaque background does not add blur effects', (WidgetTester tester) async {
await tester.pumpWidget(
- CupertinoApp(
- home: const CupertinoNavigationBar(
+ const CupertinoApp(
+ home: CupertinoNavigationBar(
middle: Text('Title'),
backgroundColor: Color(0xFFE5E5E5),
),
@@ -66,8 +66,8 @@
testWidgets('Non-opaque background adds blur effects', (WidgetTester tester) async {
await tester.pumpWidget(
- CupertinoApp(
- home: const CupertinoNavigationBar(
+ const CupertinoApp(
+ home: CupertinoNavigationBar(
middle: Text('Title'),
),
),
@@ -120,8 +120,8 @@
testWidgets('Padding works in RTL', (WidgetTester tester) async {
await tester.pumpWidget(
- CupertinoApp(
- home: const Directionality(
+ const CupertinoApp(
+ home: Directionality(
textDirection: TextDirection.rtl,
child: Align(
alignment: Alignment.topCenter,
@@ -151,8 +151,8 @@
testWidgets('Verify styles of each slot', (WidgetTester tester) async {
count = 0x000000;
await tester.pumpWidget(
- CupertinoApp(
- home: const CupertinoNavigationBar(
+ const CupertinoApp(
+ home: CupertinoNavigationBar(
leading: _ExpectStyles(color: Color(0xFF001122), index: 0x000001),
middle: _ExpectStyles(color: Color(0xFF000000), letterSpacing: -0.08, index: 0x000100),
trailing: _ExpectStyles(color: Color(0xFF001122), index: 0x010000),
@@ -165,8 +165,8 @@
testWidgets('No slivers with no large titles', (WidgetTester tester) async {
await tester.pumpWidget(
- CupertinoApp(
- home: const CupertinoPageScaffold(
+ const CupertinoApp(
+ home: CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(
middle: Text('Title'),
),
@@ -431,8 +431,8 @@
testWidgets('Auto back/close button', (WidgetTester tester) async {
await tester.pumpWidget(
- CupertinoApp(
- home: const CupertinoNavigationBar(
+ const CupertinoApp(
+ home: CupertinoNavigationBar(
middle: Text('Home page'),
),
),
@@ -486,8 +486,8 @@
testWidgets('Long back label turns into "back"', (WidgetTester tester) async {
await tester.pumpWidget(
- CupertinoApp(
- home: const Placeholder(),
+ const CupertinoApp(
+ home: Placeholder(),
),
);
@@ -529,8 +529,8 @@
testWidgets('Border should be displayed by default', (WidgetTester tester) async {
await tester.pumpWidget(
- CupertinoApp(
- home: const CupertinoNavigationBar(
+ const CupertinoApp(
+ home: CupertinoNavigationBar(
middle: Text('Title'),
),
),
@@ -551,8 +551,8 @@
testWidgets('Overrides border color', (WidgetTester tester) async {
await tester.pumpWidget(
- CupertinoApp(
- home: const CupertinoNavigationBar(
+ const CupertinoApp(
+ home: CupertinoNavigationBar(
middle: Text('Title'),
border: Border(
bottom: BorderSide(
@@ -580,8 +580,8 @@
testWidgets('Border should not be displayed when null', (WidgetTester tester) async {
await tester.pumpWidget(
- CupertinoApp(
- home: const CupertinoNavigationBar(
+ const CupertinoApp(
+ home: CupertinoNavigationBar(
middle: Text('Title'),
border: null,
),
@@ -746,8 +746,8 @@
'Standard title golden',
(WidgetTester tester) async {
await tester.pumpWidget(
- CupertinoApp(
- home: const RepaintBoundary(
+ const CupertinoApp(
+ home: RepaintBoundary(
child: CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(
middle: Text('Bling bling'),
diff --git a/packages/flutter/test/cupertino/nav_bar_transition_test.dart b/packages/flutter/test/cupertino/nav_bar_transition_test.dart
index d7715a4..a4b2e8a 100644
--- a/packages/flutter/test/cupertino/nav_bar_transition_test.dart
+++ b/packages/flutter/test/cupertino/nav_bar_transition_test.dart
@@ -14,8 +14,8 @@
String toTitle,
}) async {
await tester.pumpWidget(
- CupertinoApp(
- home: const Placeholder(),
+ const CupertinoApp(
+ home: Placeholder(),
),
);
@@ -195,8 +195,8 @@
testWidgets('Fullscreen dialogs do not create heroes',
(WidgetTester tester) async {
await tester.pumpWidget(
- CupertinoApp(
- home: const Placeholder(),
+ const CupertinoApp(
+ home: Placeholder(),
),
);
diff --git a/packages/flutter/test/cupertino/page_test.dart b/packages/flutter/test/cupertino/page_test.dart
index 5bf44ff..a6de3b2 100644
--- a/packages/flutter/test/cupertino/page_test.dart
+++ b/packages/flutter/test/cupertino/page_test.dart
@@ -146,8 +146,8 @@
testWidgets('test iOS fullscreen dialog transition', (WidgetTester tester) async {
await tester.pumpWidget(
- CupertinoApp(
- home: const Center(child: Text('Page 1')),
+ const CupertinoApp(
+ home: Center(child: Text('Page 1')),
),
);
diff --git a/packages/flutter/test/cupertino/route_test.dart b/packages/flutter/test/cupertino/route_test.dart
index 3f74462..de721c5 100644
--- a/packages/flutter/test/cupertino/route_test.dart
+++ b/packages/flutter/test/cupertino/route_test.dart
@@ -9,8 +9,8 @@
void main() {
testWidgets('Middle auto-populates with title', (WidgetTester tester) async {
await tester.pumpWidget(
- CupertinoApp(
- home: const Placeholder(),
+ const CupertinoApp(
+ home: Placeholder(),
),
);
@@ -39,8 +39,8 @@
testWidgets('Large title auto-populates with title', (WidgetTester tester) async {
await tester.pumpWidget(
- CupertinoApp(
- home: const Placeholder(),
+ const CupertinoApp(
+ home: Placeholder(),
),
);
@@ -104,8 +104,8 @@
testWidgets('Leading auto-populates with back button with previous title', (WidgetTester tester) async {
await tester.pumpWidget(
- CupertinoApp(
- home: const Placeholder(),
+ const CupertinoApp(
+ home: Placeholder(),
),
);
@@ -150,8 +150,8 @@
testWidgets('Previous title is correct on first transition frame', (WidgetTester tester) async {
await tester.pumpWidget(
- CupertinoApp(
- home: const Placeholder(),
+ const CupertinoApp(
+ home: Placeholder(),
),
);
@@ -193,8 +193,8 @@
testWidgets('Previous title stays up to date with changing routes', (WidgetTester tester) async {
await tester.pumpWidget(
- CupertinoApp(
- home: const Placeholder(),
+ const CupertinoApp(
+ home: Placeholder(),
),
);
diff --git a/packages/flutter/test/cupertino/scaffold_test.dart b/packages/flutter/test/cupertino/scaffold_test.dart
index dbeca86..6620e00 100644
--- a/packages/flutter/test/cupertino/scaffold_test.dart
+++ b/packages/flutter/test/cupertino/scaffold_test.dart
@@ -11,8 +11,8 @@
void main() {
testWidgets('Contents are behind translucent bar', (WidgetTester tester) async {
await tester.pumpWidget(
- CupertinoApp(
- home: const CupertinoPageScaffold(
+ const CupertinoApp(
+ home: CupertinoPageScaffold(
// Default nav bar is translucent.
navigationBar: CupertinoNavigationBar(
middle: Text('Title'),
@@ -276,8 +276,8 @@
testWidgets('Decorated with white background by default', (WidgetTester tester) async {
await tester.pumpWidget(
- CupertinoApp(
- home: const CupertinoPageScaffold(
+ const CupertinoApp(
+ home: CupertinoPageScaffold(
child: Center(),
),
),
@@ -292,8 +292,8 @@
testWidgets('Overrides background color', (WidgetTester tester) async {
await tester.pumpWidget(
- CupertinoApp(
- home: const CupertinoPageScaffold(
+ const CupertinoApp(
+ home: CupertinoPageScaffold(
child: Center(),
backgroundColor: Color(0xFF010203),
),
diff --git a/packages/flutter/test/material/about_test.dart b/packages/flutter/test/material/about_test.dart
index a4134a5..f71ba90 100644
--- a/packages/flutter/test/material/about_test.dart
+++ b/packages/flutter/test/material/about_test.dart
@@ -67,9 +67,9 @@
testWidgets('About box logic defaults to executable name for app name', (WidgetTester tester) async {
await tester.pumpWidget(
- MaterialApp(
+ const MaterialApp(
title: 'flutter_tester',
- home: const Material(child: AboutListTile()),
+ home: Material(child: AboutListTile()),
),
);
expect(find.text('About flutter_tester'), findsOneWidget);
@@ -89,8 +89,8 @@
});
await tester.pumpWidget(
- MaterialApp(
- home: const Center(
+ const MaterialApp(
+ home: Center(
child: LicensePage(),
),
),
diff --git a/packages/flutter/test/material/app_test.dart b/packages/flutter/test/material/app_test.dart
index b42e86c..bbd05e7 100644
--- a/packages/flutter/test/material/app_test.dart
+++ b/packages/flutter/test/material/app_test.dart
@@ -28,9 +28,9 @@
void main() {
testWidgets('Can nest apps', (WidgetTester tester) async {
await tester.pumpWidget(
- MaterialApp(
+ const MaterialApp(
home: MaterialApp(
- home: const Text('Home sweet home'),
+ home: Text('Home sweet home'),
),
),
);
@@ -57,8 +57,8 @@
await tester.pumpWidget(FocusScope(
autofocus: true,
node: focusScopeNode,
- child: MaterialApp(
- home: const Text('Home'),
+ child: const MaterialApp(
+ home: Text('Home'),
),
));
@@ -67,8 +67,8 @@
testWidgets('Can show grid without losing sync', (WidgetTester tester) async {
await tester.pumpWidget(
- MaterialApp(
- home: const StateMarker(),
+ const MaterialApp(
+ home: StateMarker(),
),
);
@@ -76,9 +76,9 @@
state1.marker = 'original';
await tester.pumpWidget(
- MaterialApp(
+ const MaterialApp(
debugShowMaterialGrid: true,
- home: const StateMarker(),
+ home: StateMarker(),
),
);
@@ -205,7 +205,7 @@
});
testWidgets('Cannot pop the initial route', (WidgetTester tester) async {
- await tester.pumpWidget(MaterialApp(home: const Text('Home')));
+ await tester.pumpWidget(const MaterialApp(home: Text('Home')));
expect(find.text('Home'), findsOneWidget);
@@ -400,9 +400,9 @@
home: const Placeholder(),
));
expect(key.currentState, isInstanceOf<NavigatorState>());
- await tester.pumpWidget(MaterialApp(
- color: const Color(0xFF112233),
- home: const Placeholder(),
+ await tester.pumpWidget(const MaterialApp(
+ color: Color(0xFF112233),
+ home: Placeholder(),
));
expect(key.currentState, isNull);
await tester.pumpWidget(MaterialApp(
diff --git a/packages/flutter/test/material/bottom_app_bar_test.dart b/packages/flutter/test/material/bottom_app_bar_test.dart
index c783cc5..2d02016 100644
--- a/packages/flutter/test/material/bottom_app_bar_test.dart
+++ b/packages/flutter/test/material/bottom_app_bar_test.dart
@@ -9,8 +9,8 @@
void main() {
testWidgets('no overlap with floating action button', (WidgetTester tester) async {
await tester.pumpWidget(
- MaterialApp(
- home: const Scaffold(
+ const MaterialApp(
+ home: Scaffold(
floatingActionButton: FloatingActionButton(
onPressed: null,
),
@@ -95,8 +95,8 @@
// _BottomAppBarClipper will try an illegal downcast.
testWidgets('toggle shape to null', (WidgetTester tester) async {
await tester.pumpWidget(
- MaterialApp(
- home: const Scaffold(
+ const MaterialApp(
+ home: Scaffold(
bottomNavigationBar: BottomAppBar(
shape: RectangularNotch(),
),
@@ -105,8 +105,8 @@
);
await tester.pumpWidget(
- MaterialApp(
- home: const Scaffold(
+ const MaterialApp(
+ home: Scaffold(
bottomNavigationBar: BottomAppBar(
shape: null,
),
@@ -115,8 +115,8 @@
);
await tester.pumpWidget(
- MaterialApp(
- home: const Scaffold(
+ const MaterialApp(
+ home: Scaffold(
bottomNavigationBar: BottomAppBar(
shape: RectangularNotch(),
),
@@ -127,8 +127,8 @@
testWidgets('no notch when notch param is null', (WidgetTester tester) async {
await tester.pumpWidget(
- MaterialApp(
- home: const Scaffold(
+ const MaterialApp(
+ home: Scaffold(
bottomNavigationBar: ShapeListener(BottomAppBar(
shape: null,
)),
@@ -159,8 +159,8 @@
testWidgets('notch no margin', (WidgetTester tester) async {
await tester.pumpWidget(
- MaterialApp(
- home: const Scaffold(
+ const MaterialApp(
+ home: Scaffold(
bottomNavigationBar: ShapeListener(
BottomAppBar(
child: SizedBox(height: 100.0),
@@ -211,8 +211,8 @@
testWidgets('notch with margin', (WidgetTester tester) async {
await tester.pumpWidget(
- MaterialApp(
- home: const Scaffold(
+ const MaterialApp(
+ home: Scaffold(
bottomNavigationBar: ShapeListener(
BottomAppBar(
child: SizedBox(height: 100.0),
@@ -263,8 +263,8 @@
testWidgets('observes safe area', (WidgetTester tester) async {
await tester.pumpWidget(
- MaterialApp(
- home: const MediaQuery(
+ const MaterialApp(
+ home: MediaQuery(
data: MediaQueryData(
padding: EdgeInsets.all(50.0),
),
@@ -287,8 +287,8 @@
testWidgets('clipBehavior is propagated', (WidgetTester tester) async {
await tester.pumpWidget(
- MaterialApp(
- home: const Scaffold(
+ const MaterialApp(
+ home: Scaffold(
bottomNavigationBar:
BottomAppBar(
child: SizedBox(height: 100.0),
@@ -303,8 +303,8 @@
expect(physicalShape.clipBehavior, Clip.none);
await tester.pumpWidget(
- MaterialApp(
- home: const Scaffold(
+ const MaterialApp(
+ home: Scaffold(
bottomNavigationBar:
BottomAppBar(
child: SizedBox(height: 100.0),
diff --git a/packages/flutter/test/material/chip_test.dart b/packages/flutter/test/material/chip_test.dart
index 082e8ae..43ff699 100644
--- a/packages/flutter/test/material/chip_test.dart
+++ b/packages/flutter/test/material/chip_test.dart
@@ -1181,8 +1181,8 @@
testWidgets('label only', (WidgetTester tester) async {
final SemanticsTester semanticsTester = SemanticsTester(tester);
- await tester.pumpWidget(MaterialApp(
- home: const Material(
+ await tester.pumpWidget(const MaterialApp(
+ home: Material(
child: RawChip(
label: Text('test'),
),
diff --git a/packages/flutter/test/material/dialog_test.dart b/packages/flutter/test/material/dialog_test.dart
index a275c4a..10ed47b 100644
--- a/packages/flutter/test/material/dialog_test.dart
+++ b/packages/flutter/test/material/dialog_test.dart
@@ -106,8 +106,8 @@
testWidgets('Simple dialog control test', (WidgetTester tester) async {
await tester.pumpWidget(
- MaterialApp(
- home: const Material(
+ const MaterialApp(
+ home: Material(
child: Center(
child: RaisedButton(
onPressed: null,
@@ -149,8 +149,8 @@
testWidgets('Barrier dismissible', (WidgetTester tester) async {
await tester.pumpWidget(
- MaterialApp(
- home: const Material(
+ const MaterialApp(
+ home: Material(
child: Center(
child: RaisedButton(
onPressed: null,
@@ -212,8 +212,8 @@
final SemanticsTester semantics = SemanticsTester(tester);
const String buttonText = 'A button covered by dialog overlay';
await tester.pumpWidget(
- MaterialApp(
- home: const Material(
+ const MaterialApp(
+ home: Material(
child: Center(
child: RaisedButton(
onPressed: null,
diff --git a/packages/flutter/test/material/drawer_test.dart b/packages/flutter/test/material/drawer_test.dart
index ff29764..9a542eb 100644
--- a/packages/flutter/test/material/drawer_test.dart
+++ b/packages/flutter/test/material/drawer_test.dart
@@ -61,8 +61,8 @@
final SemanticsTester semantics = SemanticsTester(tester);
debugDefaultTargetPlatformOverride = TargetPlatform.iOS;
await tester.pumpWidget(
- MaterialApp(
- home: const Scaffold(
+ const MaterialApp(
+ home: Scaffold(
drawer: Drawer()
),
),
@@ -86,8 +86,8 @@
testWidgets('Drawer dismiss barrier has no label on Android', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester);
await tester.pumpWidget(
- MaterialApp(
- home: const Scaffold(
+ const MaterialApp(
+ home: Scaffold(
drawer: Drawer()
),
),
diff --git a/packages/flutter/test/material/floating_action_button_test.dart b/packages/flutter/test/material/floating_action_button_test.dart
index 63bf4ed..526419c 100644
--- a/packages/flutter/test/material/floating_action_button_test.dart
+++ b/packages/flutter/test/material/floating_action_button_test.dart
@@ -36,8 +36,8 @@
testWidgets('Floating Action Button tooltip', (WidgetTester tester) async {
await tester.pumpWidget(
- MaterialApp(
- home: const Scaffold(
+ const MaterialApp(
+ home: Scaffold(
floatingActionButton: FloatingActionButton(
onPressed: null,
tooltip: 'Add',
@@ -54,8 +54,8 @@
// Regression test for: https://github.com/flutter/flutter/pull/21084
testWidgets('Floating Action Button tooltip (long press button edge)', (WidgetTester tester) async {
await tester.pumpWidget(
- MaterialApp(
- home: const Scaffold(
+ const MaterialApp(
+ home: Scaffold(
floatingActionButton: FloatingActionButton(
onPressed: null,
tooltip: 'Add',
@@ -75,8 +75,8 @@
// Regression test for: https://github.com/flutter/flutter/pull/21084
testWidgets('Floating Action Button tooltip (long press button edge - no child)', (WidgetTester tester) async {
await tester.pumpWidget(
- MaterialApp(
- home: const Scaffold(
+ const MaterialApp(
+ home: Scaffold(
floatingActionButton: FloatingActionButton(
onPressed: null,
tooltip: 'Add',
@@ -94,8 +94,8 @@
testWidgets('Floating Action Button tooltip (no child)', (WidgetTester tester) async {
await tester.pumpWidget(
- MaterialApp(
- home: const Scaffold(
+ const MaterialApp(
+ home: Scaffold(
floatingActionButton: FloatingActionButton(
onPressed: null,
tooltip: 'Add',
@@ -150,8 +150,8 @@
testWidgets('FloatingActionButton.isExtended', (WidgetTester tester) async {
await tester.pumpWidget(
- MaterialApp(
- home: const Scaffold(
+ const MaterialApp(
+ home: Scaffold(
floatingActionButton: FloatingActionButton(onPressed: null),
),
),
diff --git a/packages/flutter/test/material/persistent_bottom_sheet_test.dart b/packages/flutter/test/material/persistent_bottom_sheet_test.dart
index 9b75216..c880aee 100644
--- a/packages/flutter/test/material/persistent_bottom_sheet_test.dart
+++ b/packages/flutter/test/material/persistent_bottom_sheet_test.dart
@@ -180,8 +180,8 @@
// Remove the persistent bottomSheet
await tester.pumpWidget(
- MaterialApp(
- home: const Scaffold(
+ const MaterialApp(
+ home: Scaffold(
bottomSheet: null,
body: Placeholder(),
),
diff --git a/packages/flutter/test/material/scaffold_test.dart b/packages/flutter/test/material/scaffold_test.dart
index 2e807d7..4c23e53 100644
--- a/packages/flutter/test/material/scaffold_test.dart
+++ b/packages/flutter/test/material/scaffold_test.dart
@@ -124,7 +124,7 @@
});
testWidgets('Floating action entrance/exit animation', (WidgetTester tester) async {
- await tester.pumpWidget(MaterialApp(home: const Scaffold(
+ await tester.pumpWidget(const MaterialApp(home: Scaffold(
floatingActionButton: FloatingActionButton(
key: Key('one'),
onPressed: null,
@@ -134,7 +134,7 @@
expect(tester.binding.transientCallbackCount, 0);
- await tester.pumpWidget(MaterialApp(home: const Scaffold(
+ await tester.pumpWidget(const MaterialApp(home: Scaffold(
floatingActionButton: FloatingActionButton(
key: Key('two'),
onPressed: null,
@@ -146,11 +146,11 @@
await tester.pumpWidget(Container());
expect(tester.binding.transientCallbackCount, 0);
- await tester.pumpWidget(MaterialApp(home: const Scaffold()));
+ await tester.pumpWidget(const MaterialApp(home: Scaffold()));
expect(tester.binding.transientCallbackCount, 0);
- await tester.pumpWidget(MaterialApp(home: const Scaffold(
+ await tester.pumpWidget(const MaterialApp(home: Scaffold(
floatingActionButton: FloatingActionButton(
key: Key('one'),
onPressed: null,
@@ -569,7 +569,7 @@
const String drawerLabel = 'I am the reason for this test';
final SemanticsTester semantics = SemanticsTester(tester);
- await tester.pumpWidget(MaterialApp(home: const Scaffold(
+ await tester.pumpWidget(const MaterialApp(home: Scaffold(
body: Text(bodyLabel),
persistentFooterButtons: <Widget>[Text(persistentFooterButtonLabel)],
bottomNavigationBar: Text(bottomNavigationBarLabel),
@@ -970,7 +970,7 @@
const String endDrawerLabel = 'I am the label on end side';
final SemanticsTester semantics = SemanticsTester(tester);
- await tester.pumpWidget(MaterialApp(home: const Scaffold(
+ await tester.pumpWidget(const MaterialApp(home: Scaffold(
body: Text(bodyLabel),
drawer: Drawer(child: Text(drawerLabel)),
endDrawer: Drawer(child: Text(endDrawerLabel)),
diff --git a/packages/flutter/test/material/text_field_focus_test.dart b/packages/flutter/test/material/text_field_focus_test.dart
index 4bb79d6..a215947 100644
--- a/packages/flutter/test/material/text_field_focus_test.dart
+++ b/packages/flutter/test/material/text_field_focus_test.dart
@@ -37,8 +37,8 @@
expect(tester.testTextInput.isVisible, isFalse);
await tester.pumpWidget(
- MaterialApp(
- home: const Material(
+ const MaterialApp(
+ home: Material(
child: Center(
child: TextField(
autofocus: true,
@@ -59,8 +59,8 @@
expect(tester.testTextInput.isVisible, isFalse);
await tester.pumpWidget(
- MaterialApp(
- home: const Material(
+ const MaterialApp(
+ home: Material(
child: Center(
child: TextField(),
),
@@ -93,8 +93,8 @@
expect(tester.testTextInput.isVisible, isFalse);
await tester.pumpWidget(
- MaterialApp(
- home: const Material(
+ const MaterialApp(
+ home: Material(
child: Center(
child: TextField(
autofocus: true,
@@ -211,8 +211,8 @@
// Regression test for https://github.com/flutter/flutter/issues/16880
await tester.pumpWidget(
- MaterialApp(
- home: const Material(
+ const MaterialApp(
+ home: Material(
child: Center(
child: TextField(
decoration: null
diff --git a/packages/flutter/test/material/text_field_helper_text_test.dart b/packages/flutter/test/material/text_field_helper_text_test.dart
index ff4d5cd..f4d68b3 100644
--- a/packages/flutter/test/material/text_field_helper_text_test.dart
+++ b/packages/flutter/test/material/text_field_helper_text_test.dart
@@ -7,11 +7,11 @@
void main() {
testWidgets('TextField works correctly when changing helperText', (WidgetTester tester) async {
- await tester.pumpWidget(MaterialApp(home: const Material(child: TextField(decoration: InputDecoration(helperText: 'Awesome')))));
+ await tester.pumpWidget(const MaterialApp(home: Material(child: TextField(decoration: InputDecoration(helperText: 'Awesome')))));
expect(find.text('Awesome'), findsNWidgets(1));
await tester.pump(const Duration(milliseconds: 100));
expect(find.text('Awesome'), findsNWidgets(1));
- await tester.pumpWidget(MaterialApp(home: const Material(child: TextField(decoration: InputDecoration(errorText: 'Awesome')))));
+ await tester.pumpWidget(const MaterialApp(home: Material(child: TextField(decoration: InputDecoration(errorText: 'Awesome')))));
expect(find.text('Awesome'), findsNWidgets(2));
});
}
diff --git a/packages/flutter/test/material/text_field_test.dart b/packages/flutter/test/material/text_field_test.dart
index 5a1d8d6..46979c5 100644
--- a/packages/flutter/test/material/text_field_test.dart
+++ b/packages/flutter/test/material/text_field_test.dart
@@ -1721,8 +1721,8 @@
});
testWidgets('setting maxLength shows counter', (WidgetTester tester) async {
- await tester.pumpWidget(MaterialApp(
- home: const Material(
+ await tester.pumpWidget(const MaterialApp(
+ home: Material(
child: DefaultTextStyle(
style: TextStyle(fontFamily: 'Ahem', fontSize: 10.0),
child: Center(
@@ -1746,8 +1746,8 @@
final SemanticsTester semantics = SemanticsTester(tester);
await tester.pumpWidget(
- MaterialApp(
- home: const Material(
+ const MaterialApp(
+ home: Material(
child: DefaultTextStyle(
style: TextStyle(fontFamily: 'Ahem', fontSize: 10.0),
child: Center(
diff --git a/packages/flutter/test/material/tooltip_test.dart b/packages/flutter/test/material/tooltip_test.dart
index 8c117f8..b1bea3a 100644
--- a/packages/flutter/test/material/tooltip_test.dart
+++ b/packages/flutter/test/material/tooltip_test.dart
@@ -610,8 +610,8 @@
final SemanticsTester semantics = SemanticsTester(tester);
await tester.pumpWidget(
- MaterialApp(
- home: const Center(
+ const MaterialApp(
+ home: Center(
child: Tooltip(
message: 'Foo',
child: Text('Bar'),
@@ -645,8 +645,8 @@
final SemanticsTester semantics = SemanticsTester(tester);
await tester.pumpWidget(
- MaterialApp(
- home: const Center(
+ const MaterialApp(
+ home: Center(
child: Tooltip(
message: 'Foo',
child: Text('Bar'),
diff --git a/packages/flutter/test/widgets/banner_test.dart b/packages/flutter/test/widgets/banner_test.dart
index c11a6e0..58eb350 100644
--- a/packages/flutter/test/widgets/banner_test.dart
+++ b/packages/flutter/test/widgets/banner_test.dart
@@ -269,7 +269,7 @@
testWidgets('Banner widget in MaterialApp', (WidgetTester tester) async {
debugDisableShadows = false;
- await tester.pumpWidget(MaterialApp(home: const Placeholder()));
+ await tester.pumpWidget(const MaterialApp(home: Placeholder()));
expect(find.byType(CheckedModeBanner), paints
..save()
..translate(x: 800.0, y: 0.0)
diff --git a/packages/flutter/test/widgets/reassemble_test.dart b/packages/flutter/test/widgets/reassemble_test.dart
index c107812..adc74ba 100644
--- a/packages/flutter/test/widgets/reassemble_test.dart
+++ b/packages/flutter/test/widgets/reassemble_test.dart
@@ -7,8 +7,8 @@
void main() {
testWidgets('reassemble does not crash', (WidgetTester tester) async {
- await tester.pumpWidget(MaterialApp(
- home: const Text('Hello World')
+ await tester.pumpWidget(const MaterialApp(
+ home: Text('Hello World')
));
await tester.pump();
tester.binding.reassembleApplication();
diff --git a/packages/flutter_test/test/test_text_input_test.dart b/packages/flutter_test/test/test_text_input_test.dart
index 2c89f56..2bed613 100644
--- a/packages/flutter_test/test/test_text_input_test.dart
+++ b/packages/flutter_test/test/test_text_input_test.dart
@@ -10,8 +10,8 @@
testWidgets('receiveAction() forwards exception when exception occurs during action processing',
(WidgetTester tester) async {
// Setup a widget that can receive focus so that we can open the keyboard.
- final Widget widget = MaterialApp(
- home: const Material(
+ const Widget widget = MaterialApp(
+ home: Material(
child: TextField(),
),
);
diff --git a/packages/flutter_test/test/widget_tester_test.dart b/packages/flutter_test/test/widget_tester_test.dart
index c26094f..ecb5ba0 100644
--- a/packages/flutter_test/test/widget_tester_test.dart
+++ b/packages/flutter_test/test/widget_tester_test.dart
@@ -533,8 +533,8 @@
group('getSemanticsData', () {
testWidgets('throws when there are no semantics', (WidgetTester tester) async {
await tester.pumpWidget(
- MaterialApp(
- home: const Scaffold(
+ const MaterialApp(
+ home: Scaffold(
body: Text('hello'),
),
),