[go: nahoru, domu]

Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ScaffoldMessenger #64101

Merged
merged 11 commits into from
Sep 3, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 35 additions & 21 deletions packages/flutter/lib/src/material/app.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import 'floating_action_button.dart';
import 'icons.dart';
import 'material_localizations.dart';
import 'page.dart';
import 'scaffold.dart';
import 'theme.dart';

/// [MaterialApp] uses this [TextStyle] as its [DefaultTextStyle] to encourage
Expand Down Expand Up @@ -168,6 +169,7 @@ class MaterialApp extends StatefulWidget {
const MaterialApp({
Key key,
this.navigatorKey,
this.scaffoldMessengerKey,
this.home,
this.routes = const <String, WidgetBuilder>{},
this.initialRoute,
Expand Down Expand Up @@ -215,6 +217,7 @@ class MaterialApp extends StatefulWidget {
/// Creates a [MaterialApp] that uses the [Router] instead of a [Navigator].
const MaterialApp.router({
Key key,
this.scaffoldMessengerKey,
this.routeInformationProvider,
@required this.routeInformationParser,
@required this.routerDelegate,
Expand Down Expand Up @@ -263,6 +266,14 @@ class MaterialApp extends StatefulWidget {
/// {@macro flutter.widgets.widgetsApp.navigatorKey}
final GlobalKey<NavigatorState> navigatorKey;

/// A key to use when building the [ScaffoldMessenger].
///
/// If a [scaffoldMessengerKey] is specified, the [ScaffoldMessenger] can be
/// directly manipulated without first obtaining it from a [BuildContext] via
/// [ScaffoldMessenger.of]: from the [scaffoldMessengerKey], use the
/// [GlobalKey.currentState] getter.
final GlobalKey<ScaffoldMessengerState> scaffoldMessengerKey;

/// {@macro flutter.widgets.widgetsApp.home}
final Widget home;

Expand Down Expand Up @@ -722,27 +733,30 @@ class _MaterialAppState extends State<MaterialApp> {
}
theme ??= widget.theme ?? ThemeData.light();

return AnimatedTheme(
data: theme,
isMaterialAppTheme: true,
child: widget.builder != null
? Builder(
builder: (BuildContext context) {
// Why are we surrounding a builder with a builder?
//
// The widget.builder may contain code that invokes
// Theme.of(), which should return the theme we selected
// above in AnimatedTheme. However, if we invoke
// widget.builder() directly as the child of AnimatedTheme
// then there is no Context separating them, and the
// widget.builder() will not find the theme. Therefore, we
// surround widget.builder with yet another builder so that
// a context separates them and Theme.of() correctly
// resolves to the theme we passed to AnimatedTheme.
return widget.builder(context, child);
},
)
: child,
return ScaffoldMessenger(
key: widget.scaffoldMessengerKey,
child: AnimatedTheme(
data: theme,
isMaterialAppTheme: true,
child: widget.builder != null
? Builder(
builder: (BuildContext context) {
// Why are we surrounding a builder with a builder?
//
// The widget.builder may contain code that invokes
// Theme.of(), which should return the theme we selected
// above in AnimatedTheme. However, if we invoke
// widget.builder() directly as the child of AnimatedTheme
// then there is no Context separating them, and the
// widget.builder() will not find the theme. Therefore, we
// surround widget.builder with yet another builder so that
// a context separates them and Theme.of() correctly
// resolves to the theme we passed to AnimatedTheme.
return widget.builder(context, child);
},
)
: child,
)
);
}

Expand Down
2 changes: 1 addition & 1 deletion packages/flutter/lib/src/material/app_bar.dart
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ class _ToolbarContainerLayout extends SingleChildLayoutDelegate {
/// icon: const Icon(Icons.add_alert),
/// tooltip: 'Show Snackbar',
/// onPressed: () {
/// scaffoldKey.currentState.showSnackBar(snackBar);
/// ScaffoldMessenger.of(context).showSnackBar(snackBar);
/// },
/// ),
/// IconButton(
Expand Down
33 changes: 32 additions & 1 deletion packages/flutter/lib/src/material/debug.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import 'package:flutter/widgets.dart';

import 'material.dart';
import 'material_localizations.dart';
import 'scaffold.dart' show Scaffold;
import 'scaffold.dart' show Scaffold, ScaffoldMessenger;

/// Asserts that the given context has a [Material] ancestor.
///
Expand Down Expand Up @@ -125,3 +125,34 @@ bool debugCheckHasScaffold(BuildContext context) {
}());
return true;
}

/// Asserts that the given context has a [ScaffoldMessenger] ancestor.
///
/// Used by various widgets to make sure that they are only used in an
/// appropriate context.
///
/// To invoke this function, use the following pattern, typically in the
/// relevant Widget's build method:
///
/// ```dart
/// assert(debugCheckHasScaffoldMessenger(context));
/// ```
///
/// Does nothing if asserts are disabled. Always returns true.
bool debugCheckHasScaffoldMessenger(BuildContext context) {
assert(() {
if (context.widget is! ScaffoldMessenger && context.findAncestorWidgetOfExactType<ScaffoldMessenger>() == null) {
throw FlutterError.fromParts(<DiagnosticsNode>[
ErrorSummary('No ScaffoldMessenger widget found.'),
ErrorDescription('${context.widget.runtimeType} widgets require a ScaffoldMessenger widget ancestor.'),
...context.describeMissingAncestor(expectedAncestorType: ScaffoldMessenger),
ErrorHint(
'Typically, the ScaffoldMessenger widget is introduced by the MaterialApp '
'at the top of your application widget tree.'
)
]);
}
return true;
}());
return true;
}
Loading