of static method

ScaffoldState of(
  1. BuildContext 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.

This method can be expensive (it walks the element tree).

Typical usage of the Scaffold.of function is to call it from within the build method of a child of a Scaffold.

To see it in action, copy and run this code snippet on DartPad.

import 'package:material_ui/material_ui.dart';

/// Flutter code sample for [Scaffold.of].

void main() => runApp(const OfExampleApp());

class OfExampleApp extends StatelessWidget {
  const OfExampleApp({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(primarySwatch: Colors.blue),
      home: Scaffold(
        body: const MyScaffoldBody(),
        appBar: AppBar(title: const Text('Scaffold.of Example')),
      ),
      color: Colors.white,
    );
  }
}

class MyScaffoldBody extends StatelessWidget {
  const MyScaffoldBody({super.key});

  @override
  Widget build(BuildContext context) {
    return Center(
      child: ElevatedButton(
        child: const Text('SHOW BOTTOM SHEET'),
        onPressed: () {
          Scaffold.of(context).showBottomSheet((BuildContext context) {
            return Container(
              alignment: .center,
              height: 200,
              color: Colors.amber,
              child: Center(
                child: Column(
                  mainAxisSize: .min,
                  children: <Widget>[
                    const Text('BottomSheet'),
                    ElevatedButton(
                      child: const Text('Close BottomSheet'),
                      onPressed: () {
                        Navigator.pop(context);
                      },
                    ),
                  ],
                ),
              ),
            );
          });
        },
      ),
    );
  }
}

When the Scaffold is actually created in the same build function, the context argument to the build function can't be used to find the Scaffold (since it's "above" the widget being returned in the widget tree). In such cases, the following technique with a Builder can be used to provide a new scope with a BuildContext that is "under" the Scaffold:

To see it in action, copy and run this code snippet on DartPad.

import 'package:material_ui/material_ui.dart';

/// Flutter code sample for [Scaffold.of].

void main() => runApp(const OfExampleApp());

class OfExampleApp extends StatelessWidget {
  const OfExampleApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(home: OfExample());
  }
}

class OfExample extends StatelessWidget {
  const OfExample({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Scaffold.of Example')),
      body: Builder(
        // Create an inner BuildContext so that the onPressed methods
        // can refer to the Scaffold with Scaffold.of().
        builder: (BuildContext context) {
          return Center(
            child: ElevatedButton(
              child: const Text('SHOW BOTTOM SHEET'),
              onPressed: () {
                Scaffold.of(context).showBottomSheet((BuildContext context) {
                  return Container(
                    alignment: .center,
                    height: 200,
                    color: Colors.amber,
                    child: Center(
                      child: Column(
                        mainAxisSize: .min,
                        children: <Widget>[
                          const Text('BottomSheet'),
                          ElevatedButton(
                            child: const Text('Close BottomSheet'),
                            onPressed: () {
                              Navigator.pop(context);
                            },
                          ),
                        ],
                      ),
                    ),
                  );
                });
              },
            ),
          );
        },
      ),
    );
  }
}

A more efficient solution is to split your build function into several widgets. This introduces a new context from which you can obtain the Scaffold. In this solution, you would have an outer widget that creates the Scaffold populated by instances of your new inner widgets, and then in these inner widgets you would use Scaffold.of.

A less elegant but more expedient solution is assign a GlobalKey to the Scaffold, then use the key.currentState property to obtain the 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, use maybeOf instead.

Implementation

// TODO(framework): Replace the following block with a @dartpad directive
// when it's supported. https://github.com/dart-lang/dartdoc/issues/4123
/// {@macro material_ui.dartpad_guide}
///
/// {@example /example/lib/scaffold/scaffold.of.0.dart#body}
///
/// </callout-box>
///
/// <callout-box>
///
/// When the [Scaffold] is actually created in the same `build` function, the
/// `context` argument to the `build` function can't be used to find the
/// [Scaffold] (since it's "above" the widget being returned in the widget
/// tree). In such cases, the following technique with a [Builder] can be used
/// to provide a new scope with a [BuildContext] that is "under" the
/// [Scaffold]:
///
// TODO(framework): Replace the following block with a @dartpad directive
// when it's supported. https://github.com/dart-lang/dartdoc/issues/4123
/// {@macro material_ui.dartpad_guide}
///
/// {@example /example/lib/scaffold/scaffold.of.1.dart#body}
///
/// </callout-box>
///
/// A more efficient solution is to split your build function into several
/// widgets. This introduces a new context from which you can obtain the
/// [Scaffold]. In this solution, you would have an outer widget that creates
/// the [Scaffold] populated by instances of your new inner widgets, and then
/// in these inner widgets you would use [Scaffold.of].
///
/// A less elegant but more expedient solution is assign a [GlobalKey] to the
/// [Scaffold], then use the `key.currentState` property to obtain the
/// [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], use [maybeOf] instead.
static ScaffoldState of(BuildContext context) {
  final ScaffoldState? result = context.findAncestorStateOfType<ScaffoldState>();
  if (result != null) {
    return result;
  }
  throw FlutterError.fromParts(<DiagnosticsNode>[
    ErrorSummary('Scaffold.of() called with a context that does not contain a Scaffold.'),
    ErrorDescription(
      'No Scaffold ancestor could be found starting from the context that was passed to Scaffold.of(). '
      'This usually happens when the context provided is from the same StatefulWidget as that '
      'whose build function actually creates the Scaffold widget being sought.',
    ),
    ErrorHint(
      'There are several ways to avoid this problem. The simplest is to use a Builder to get a '
      'context that is "under" the Scaffold. For an example of this, please see the '
      'documentation for Scaffold.of():\n'
      '  https://api.flutter.dev/flutter/material/Scaffold/of.html',
    ),
    ErrorHint(
      'A more efficient solution is to split your build function into several widgets. This '
      'introduces a new context from which you can obtain the Scaffold. In this solution, '
      'you would have an outer widget that creates the Scaffold populated by instances of '
      'your new inner widgets, and then in these inner widgets you would use Scaffold.of().\n'
      'A less elegant but more expedient solution is assign a GlobalKey to the Scaffold, '
      'then use the key.currentState property to obtain the ScaffoldState rather than '
      'using the Scaffold.of() function.',
    ),
    context.describeElement('The context used was'),
  ]);
}