Unverified Commit 4fa5fe5f authored by Greg Spencer's avatar Greg Spencer Committed by GitHub

Remove nullOk from Scaffold.of and ScaffoldMessenger.of, create maybeOf for both (#68908)

parent e5f7726c
......@@ -487,11 +487,11 @@ class _AppBarState extends State<AppBar> {
static const Color _defaultShadowColor = Color(0xFF000000);
void _handleDrawerButton() {
Scaffold.of(context)!.openDrawer();
Scaffold.of(context).openDrawer();
}
void _handleDrawerButtonEnd() {
Scaffold.of(context)!.openEndDrawer();
Scaffold.of(context).openEndDrawer();
}
@override
......@@ -500,7 +500,7 @@ class _AppBarState extends State<AppBar> {
assert(debugCheckHasMaterialLocalizations(context));
final ThemeData? theme = Theme.of(context);
final AppBarTheme appBarTheme = AppBarTheme.of(context);
final ScaffoldState? scaffold = Scaffold.of(context, nullOk: true);
final ScaffoldState? scaffold = Scaffold.maybeOf(context);
final ModalRoute<dynamic>? parentRoute = ModalRoute.of(context);
final bool hasDrawer = scaffold?.hasDrawer ?? false;
......
......@@ -737,7 +737,7 @@ PersistentBottomSheetController<T> showBottomSheet<T>({
assert(builder != null);
assert(debugCheckHasScaffold(context));
return Scaffold.of(context)!.showBottomSheet<T>(
return Scaffold.of(context).showBottomSheet<T>(
builder,
backgroundColor: backgroundColor,
elevation: elevation,
......
......@@ -204,16 +204,34 @@ class ScaffoldMessenger extends StatefulWidget {
/// ```
/// {@end-tool}
///
/// If there is no [ScaffoldMessenger] in scope, then this will return null.
/// If there is no [ScaffoldMessenger] in scope, then this will assert in
/// debug mode, and throw an exception in release mode.
///
/// See also:
///
/// * [maybeOf], which is a similar function but will return null instead of
/// throwing if there is no [ScaffoldMessenger] ancestor.
/// * [debugCheckHasScaffoldMessenger], which asserts that the given context
/// has a [ScaffoldMessenger] ancestor.
static ScaffoldMessengerState? of(BuildContext context, { bool nullOk = false }) {
assert(nullOk != null);
static ScaffoldMessengerState of(BuildContext context) {
assert(context != null);
assert(debugCheckHasScaffoldMessenger(context));
final _ScaffoldMessengerScope scope = context.dependOnInheritedWidgetOfExactType<_ScaffoldMessengerScope>()!;
return scope._scaffoldMessengerState;
}
assert(nullOk || debugCheckHasScaffoldMessenger(context));
/// The state from the closest instance of this class that encloses the given
/// context, if any.
///
/// Will return null if a [ScaffoldMessenger] is not found in the given context.
///
/// See also:
///
/// * [of], which is a similar function, except that it will throw an
/// exception if a [ScaffoldMessenger] is not found in the given context.
static ScaffoldMessengerState? maybeOf(BuildContext context) {
assert(context != null);
final _ScaffoldMessengerScope? scope = context.dependOnInheritedWidgetOfExactType<_ScaffoldMessengerScope>();
return scope?._scaffoldMessengerState;
......@@ -1755,7 +1773,11 @@ class Scaffold extends StatefulWidget {
/// By default, the drag gesture is enabled.
final bool endDrawerEnableOpenDragGesture;
/// The state from the closest instance of this class that encloses the given context.
/// Finds the [ScaffoldState] from the closest instance of this class that
/// encloses the given context.
///
/// If no instance of this class encloses the given context, will cause an
/// assert in debug mode, and throw an exception in release mode.
///
/// {@tool dartpad --template=freeform}
/// Typical usage of the [Scaffold.of] function is to call it from within the
......@@ -1892,12 +1914,11 @@ class Scaffold extends StatefulWidget {
/// [ScaffoldState] rather than using the [Scaffold.of] function.
///
/// If there is no [Scaffold] in scope, then this will throw an exception.
/// To return null if there is no [Scaffold], then pass `nullOk: true`.
static ScaffoldState? of(BuildContext context, { bool nullOk = false }) {
assert(nullOk != null);
/// To return null if there is no [Scaffold], use [maybeOf] instead.
static ScaffoldState of(BuildContext context) {
assert(context != null);
final ScaffoldState? result = context.findAncestorStateOfType<ScaffoldState>();
if (nullOk || result != null)
if (result != null)
return result;
throw FlutterError.fromParts(<DiagnosticsNode>[
ErrorSummary(
......@@ -1927,6 +1948,22 @@ class Scaffold extends StatefulWidget {
]);
}
/// Finds the [ScaffoldState] from the closest instance of this class that
/// encloses the given context.
///
/// If no instance of this class encloses the given context, will return null.
/// To throw an exception instead, use [of] instead of this function.
///
/// See also:
///
/// * [of], a similar function to this one that throws if no instance
/// encloses the given context. Also includes some sample code in its
/// documentation.
static ScaffoldState? maybeOf(BuildContext context) {
assert(context != null);
return context.findAncestorStateOfType<ScaffoldState>();
}
/// Returns a [ValueListenable] for the [ScaffoldGeometry] for the closest
/// [Scaffold] ancestor of the given context.
///
......@@ -2714,7 +2751,7 @@ class ScaffoldState extends State<Scaffold> with TickerProviderStateMixin {
void didChangeDependencies() {
// nullOk is valid here since both the Scaffold and ScaffoldMessenger are
// currently available for managing SnackBars.
final ScaffoldMessengerState? _currentScaffoldMessenger = ScaffoldMessenger.of(context, nullOk: true);
final ScaffoldMessengerState? _currentScaffoldMessenger = ScaffoldMessenger.maybeOf(context);
// If our ScaffoldMessenger has changed, unregister with the old one first.
if (_scaffoldMessenger != null &&
(_currentScaffoldMessenger == null || _scaffoldMessenger != _currentScaffoldMessenger)) {
......@@ -3304,7 +3341,7 @@ class _StandardBottomSheetState extends State<_StandardBottomSheet> {
bool extentChanged(DraggableScrollableNotification notification) {
final double extentRemaining = 1.0 - notification.extent;
final ScaffoldState scaffold = Scaffold.of(context)!;
final ScaffoldState scaffold = Scaffold.of(context);
if (extentRemaining < _kBottomSheetDominatesPercentage) {
scaffold._floatingActionButtonVisibilityValue = extentRemaining * _kBottomSheetDominatesPercentage * 10;
scaffold.showBodyScrim(true, math.max(
......
......@@ -123,7 +123,7 @@ class _SnackBarActionState extends State<SnackBarAction> {
_haveTriggeredAction = true;
});
widget.onPressed();
Scaffold.of(context)!.hideCurrentSnackBar(reason: SnackBarClosedReason.action);
Scaffold.of(context).hideCurrentSnackBar(reason: SnackBarClosedReason.action);
}
@override
......@@ -529,14 +529,14 @@ class _SnackBarState extends State<SnackBar> {
container: true,
liveRegion: true,
onDismiss: () {
Scaffold.of(context)!.removeCurrentSnackBar(reason: SnackBarClosedReason.dismiss);
Scaffold.of(context).removeCurrentSnackBar(reason: SnackBarClosedReason.dismiss);
},
child: Dismissible(
key: const Key('dismissible'),
direction: DismissDirection.down,
resizeDuration: null,
onDismissed: (DismissDirection direction) {
Scaffold.of(context)!.removeCurrentSnackBar(reason: SnackBarClosedReason.swipe);
Scaffold.of(context).removeCurrentSnackBar(reason: SnackBarClosedReason.swipe);
},
child: snackBar,
),
......
......@@ -647,7 +647,7 @@ void main() {
builder: (BuildContext context) {
return FloatingActionButton(
onPressed: () {
ScaffoldMessenger.of(context)!.showSnackBar(
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Snacky!')),
);
},
......
......@@ -355,7 +355,7 @@ void main() {
builder: (BuildContext context) {
return GestureDetector(
onTap: () {
Scaffold.of(context)!.showBottomSheet<void>((BuildContext context) {
Scaffold.of(context).showBottomSheet<void>((BuildContext context) {
return Container(
key: sheetKey,
color: Colors.blue[500],
......@@ -1900,7 +1900,7 @@ void main() {
MaterialApp(
home: Builder(
builder: (BuildContext context) {
Scaffold.of(context)!.showBottomSheet<void>((BuildContext context) {
Scaffold.of(context).showBottomSheet<void>((BuildContext context) {
return Container();
});
return Container();
......@@ -2033,7 +2033,7 @@ void main() {
});
});
testWidgets('ScaffoldMessenger.of can return null', (WidgetTester tester) async {
testWidgets('ScaffoldMessenger.maybeOf can return null if not found', (WidgetTester tester) async {
ScaffoldMessengerState? scaffoldMessenger;
const Key tapTarget = Key('tap-target');
await tester.pumpWidget(Directionality(
......@@ -2045,7 +2045,7 @@ void main() {
builder: (BuildContext context) {
return GestureDetector(
onTap: () {
scaffoldMessenger = ScaffoldMessenger.of(context, nullOk: true);
scaffoldMessenger = ScaffoldMessenger.maybeOf(context);
},
behavior: HitTestBehavior.opaque,
child: Container(
......@@ -2064,7 +2064,7 @@ void main() {
expect(scaffoldMessenger, isNull);
});
testWidgets('ScaffoldMessenger.of will assert if !nullOk', (WidgetTester tester) async {
testWidgets('ScaffoldMessenger.of will assert if not found', (WidgetTester tester) async {
const Key tapTarget = Key('tap-target');
final List<dynamic> exceptions = <dynamic>[];
......
......@@ -71,7 +71,7 @@ void main() {
builder: (BuildContext context) {
return GestureDetector(
onTap: () {
ScaffoldMessenger.of(context)!.showSnackBar(SnackBar(
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: const Text(text),
duration: const Duration(seconds: 2),
action: SnackBarAction(label: 'ACTION', onPressed: () {}),
......@@ -109,7 +109,7 @@ void main() {
builder: (BuildContext context) {
return GestureDetector(
onTap: () {
ScaffoldMessenger.of(context)!.showSnackBar(SnackBar(
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: const Text(text),
duration: const Duration(seconds: 2),
action: SnackBarAction(label: action, onPressed: () {}),
......@@ -153,7 +153,7 @@ void main() {
builder: (BuildContext context) {
return GestureDetector(
onTap: () {
ScaffoldMessenger.of(context)!.showSnackBar(SnackBar(
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
backgroundColor: backgroundColor,
elevation: elevation,
shape: shape,
......@@ -200,7 +200,7 @@ void main() {
builder: (BuildContext context) {
return GestureDetector(
onTap: () {
ScaffoldMessenger.of(context)!.showSnackBar(SnackBar(
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: const Text('I am a snack bar.'),
duration: const Duration(seconds: 2),
action: SnackBarAction(label: 'ACTION', onPressed: () {}),
......@@ -242,7 +242,7 @@ void main() {
builder: (BuildContext context) {
return GestureDetector(
onTap: () {
ScaffoldMessenger.of(context)!.showSnackBar(SnackBar(
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: const Text('I am a snack bar.'),
duration: const Duration(seconds: 2),
action: SnackBarAction(label: 'ACTION', onPressed: () {}),
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment