@@ -24,6 +24,10 @@ import 'widget_inspector.dart';
24
24
25
25
export 'dart:ui' show AppLifecycleState, Locale;
26
26
27
+ // Examples can assume:
28
+ // late FlutterView myFlutterView;
29
+ // class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) => const Placeholder(); }
30
+
27
31
/// Interface for classes that register with the Widgets layer binding.
28
32
///
29
33
/// This can be used by any class, not just widgets. It provides an interface
@@ -1152,21 +1156,28 @@ mixin WidgetsBinding on BindingBase, ServicesBinding, SchedulerBinding, GestureB
1152
1156
}
1153
1157
}
1154
1158
1155
- /// Inflate the given widget and attach it to the screen.
1159
+ /// Inflate the given widget and attach it to the view.
1160
+ ///
1161
+ // TODO(goderbauer): Update the paragraph below to include the Window widget once that exists.
1162
+ /// The [runApp] method renders the provided `app` widget into the
1163
+ /// [PlatformDispatcher.implicitView] by wrapping it in a [View] widget, which
1164
+ /// will bootstrap the render tree for the app. Apps that want to control which
1165
+ /// [FlutterView] they render into can use [runWidget] instead.
1156
1166
///
1157
1167
/// The widget is given constraints during layout that force it to fill the
1158
- /// entire screen . If you wish to align your widget to one side of the screen
1168
+ /// entire view . If you wish to align your widget to one side of the view
1159
1169
/// (e.g., the top), consider using the [Align] widget. If you wish to center
1160
1170
/// your widget, you can also use the [Center] widget.
1161
1171
///
1162
- /// Calling [runApp] again will detach the previous root widget from the screen
1172
+ /// Calling [runApp] again will detach the previous root widget from the view
1163
1173
/// and attach the given widget in its place. The new widget tree is compared
1164
1174
/// against the previous widget tree and any differences are applied to the
1165
1175
/// underlying render tree, similar to what happens when a [StatefulWidget]
1166
1176
/// rebuilds after calling [State.setState] .
1167
1177
///
1168
1178
/// Initializes the binding using [WidgetsFlutterBinding] if necessary.
1169
1179
///
1180
+ /// {@template flutter.widgets.runApp.shutdown}
1170
1181
/// ## Application shutdown
1171
1182
///
1172
1183
/// This widget tree is not torn down when the application shuts down, because
@@ -1178,29 +1189,32 @@ mixin WidgetsBinding on BindingBase, ServicesBinding, SchedulerBinding, GestureB
1178
1189
/// Applications are responsible for ensuring that they are well-behaved
1179
1190
/// even in the face of a rapid unscheduled termination.
1180
1191
///
1181
- /// To artificially cause the entire widget tree to be disposed, consider
1182
- /// calling [runApp] with a widget such as [SizedBox.shrink] .
1183
- ///
1184
1192
/// To listen for platform shutdown messages (and other lifecycle changes),
1185
1193
/// consider the [AppLifecycleListener] API.
1194
+ /// {@endtemplate}
1186
1195
///
1187
- /// ## Dismissing Flutter UI via platform native methods
1196
+ /// To artificially cause the entire widget tree to be disposed, consider
1197
+ /// calling [runApp] with a widget such as [SizedBox.shrink] .
1188
1198
///
1189
1199
/// {@template flutter.widgets.runApp.dismissal}
1200
+ /// ## Dismissing Flutter UI via platform native methods
1201
+ ///
1190
1202
/// An application may have both Flutter and non-Flutter UI in it. If the
1191
1203
/// application calls non-Flutter methods to remove Flutter based UI such as
1192
1204
/// platform native API to manipulate the platform native navigation stack,
1193
1205
/// the framework does not know if the developer intends to eagerly free
1194
1206
/// resources or not. The widget tree remains mounted and ready to render
1195
1207
/// as soon as it is displayed again.
1208
+ /// {@endtemplate}
1196
1209
///
1197
1210
/// To release resources more eagerly, establish a [platform channel] (https://flutter.dev/platform-channels/)
1198
1211
/// and use it to call [runApp] with a widget such as [SizedBox.shrink] when
1199
1212
/// the framework should dispose of the active widget tree.
1200
- /// {@endtemplate}
1201
1213
///
1202
1214
/// See also:
1203
1215
///
1216
+ /// * [runWidget] , which bootstraps a widget tree without assuming the
1217
+ /// [FlutterView] into which it will be rendered.
1204
1218
/// * [WidgetsBinding.attachRootWidget] , which creates the root widget for the
1205
1219
/// widget hierarchy.
1206
1220
/// * [RenderObjectToWidgetAdapter.attachToRenderTree] , which creates the root
@@ -1209,9 +1223,75 @@ mixin WidgetsBinding on BindingBase, ServicesBinding, SchedulerBinding, GestureB
1209
1223
/// ensure the widget, element, and render trees are all built.
1210
1224
void runApp (Widget app) {
1211
1225
final WidgetsBinding binding = WidgetsFlutterBinding .ensureInitialized ();
1212
- assert (binding.debugCheckZone ('runApp' ));
1226
+ _runWidget (binding.wrapWithDefaultView (app), binding, 'runApp' );
1227
+ }
1228
+
1229
+ /// Inflate the given widget and bootstrap the widget tree.
1230
+ ///
1231
+ // TODO(goderbauer): Update the paragraph below to include the Window widget once that exists.
1232
+ /// Unlike [runApp] , this method does not define a [FlutterView] into which the
1233
+ /// provided `app` widget is rendered into. It is up to the caller to include at
1234
+ /// least one [View] widget in the provided `app` widget that will bootstrap a
1235
+ /// render tree and define the [FlutterView] into which content is rendered.
1236
+ /// [RenderObjectWidget] s without an ancestor [View] widget will result in an
1237
+ /// exception. Apps that want to render into the default view without dealing
1238
+ /// with view management should consider calling [runApp] instead.
1239
+ ///
1240
+ /// {@tool snippet}
1241
+ /// The sample shows how to utilize [runWidget] to specify the [FlutterView]
1242
+ /// into which the `MyApp` widget will be drawn:
1243
+ ///
1244
+ /// ```dart
1245
+ /// runWidget(
1246
+ /// View(
1247
+ /// view: myFlutterView,
1248
+ /// child: const MyApp(),
1249
+ /// ),
1250
+ /// );
1251
+ /// ```
1252
+ /// {@end-tool}
1253
+ ///
1254
+ /// Calling [runWidget] again will detach the previous root widget and attach
1255
+ /// the given widget in its place. The new widget tree is compared against the
1256
+ /// previous widget tree and any differences are applied to the underlying
1257
+ /// render tree, similar to what happens when a [StatefulWidget] rebuilds after
1258
+ /// calling [State.setState] .
1259
+ ///
1260
+ /// Initializes the binding using [WidgetsFlutterBinding] if necessary.
1261
+ ///
1262
+ /// {@macro flutter.widgets.runApp.shutdown}
1263
+ ///
1264
+ /// To artificially cause the entire widget tree to be disposed, consider
1265
+ /// calling [runWidget] with a [ViewCollection] that does not specify any
1266
+ /// [ViewCollection.views] .
1267
+ ///
1268
+ /// ## Dismissing Flutter UI via platform native methods
1269
+ ///
1270
+ /// {@macro flutter.widgets.runApp.dismissal}
1271
+ ///
1272
+ /// To release resources more eagerly, establish a [platform channel] (https://flutter.dev/platform-channels/)
1273
+ /// and use it to remove the [View] whose widget resources should be released
1274
+ /// from the `app` widget tree provided to [runWidget] .
1275
+ ///
1276
+ /// See also:
1277
+ ///
1278
+ /// * [runApp] , which bootstraps a widget tree and renders it into a default
1279
+ /// [FlutterView].
1280
+ /// * [WidgetsBinding.attachRootWidget] , which creates the root widget for the
1281
+ /// widget hierarchy.
1282
+ /// * [RenderObjectToWidgetAdapter.attachToRenderTree] , which creates the root
1283
+ /// element for the element hierarchy.
1284
+ /// * [WidgetsBinding.handleBeginFrame] , which pumps the widget pipeline to
1285
+ /// ensure the widget, element, and render trees are all built.
1286
+ void runWidget (Widget app) {
1287
+ final WidgetsBinding binding = WidgetsFlutterBinding .ensureInitialized ();
1288
+ _runWidget (app, binding, 'runWidget' );
1289
+ }
1290
+
1291
+ void _runWidget (Widget app, WidgetsBinding binding, String debugEntryPoint) {
1292
+ assert (binding.debugCheckZone (debugEntryPoint));
1213
1293
binding
1214
- ..scheduleAttachRootWidget (binding. wrapWithDefaultView ( app) )
1294
+ ..scheduleAttachRootWidget (app)
1215
1295
..scheduleWarmUpFrame ();
1216
1296
}
1217
1297
0 commit comments