showCupertinoDialog<T> function Null safety

Future<T?> showCupertinoDialog <T>(
  1. {required BuildContext context,
  2. required WidgetBuilder builder,
  3. String? barrierLabel,
  4. bool useRootNavigator: true,
  5. bool barrierDismissible: false,
  6. RouteSettings? routeSettings}
)

Displays an iOS-style dialog above the current contents of the app, with iOS-style entrance and exit animations, modal barrier color, and modal barrier behavior (by default, the dialog is not dismissible with a tap on the barrier).

This function takes a builder which typically builds a CupertinoAlertDialog widget. Content below the dialog is dimmed with a ModalBarrier. The widget returned by the builder does not share a context with the location that showCupertinoDialog is originally called from. Use a StatefulBuilder or a custom StatefulWidget if the dialog needs to update dynamically.

The context argument is used to look up the Navigator for the dialog. It is only used when the method is called. Its corresponding widget can be safely removed from the tree before the dialog is closed.

The useRootNavigator argument is used to determine whether to push the dialog to the Navigator furthest from or nearest to the given context. By default, useRootNavigator is true and the dialog route created by this method is pushed to the root navigator.

If the application has multiple Navigator objects, it may be necessary to call Navigator.of(context, rootNavigator: true).pop(result) to close the dialog rather than just Navigator.pop(context, result).

Returns a Future that resolves to the value (if any) that was passed to Navigator.pop when the dialog was closed.

State Restoration in Dialogs

Using this method will not enable state restoration for the dialog. In order to enable state restoration for a dialog, use Navigator.restorablePush or Navigator.restorablePushNamed with CupertinoDialogRoute.

For more information about state restoration, see RestorationManager.

This sample demonstrates how to create a restorable Cupertino dialog. This is accomplished by enabling state restoration by specifying CupertinoApp.restorationScopeId and using Navigator.restorablePush to push CupertinoDialogRoute when the CupertinoButton is tapped.

To test state restoration on Android:

  1. Turn on "Don't keep activities", which destroys the Android activity as soon as the user leaves it. This option should become available when Developer Options are turned on for the device.
  2. Run the code sample on an Android device.
  3. Create some in-memory state in the app on the phone, e.g. by navigating to a different screen.
  4. Background the Flutter app, then return to it. It will restart and restore its state.

To test state restoration on iOS:

  1. Open ios/Runner.xcworkspace/ in Xcode.
  2. (iOS 14+ only): Switch to build in profile or release mode, as launching an app from the home screen is not supported in debug mode.
  3. Press the Play button in Xcode to build and run the app.
  4. Create some in-memory state in the app on the phone, e.g. by navigating to a different screen.
  5. Background the app on the phone, e.g. by going back to the home screen.
  6. Press the Stop button in Xcode to terminate the app while running in the background.
  7. Open the app again on the phone (not via Xcode). It will restart and restore its state.
import 'package:flutter/cupertino.dart';

// ...

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return CupertinoApp(
      restorationScopeId: 'app',
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  static Route<Object?> _dialogBuilder(BuildContext context, Object? arguments) {
    return CupertinoDialogRoute<void>(
      context: context,
      builder: (BuildContext context) {
        return const CupertinoAlertDialog(
          title: Text('Title'),
          content: Text('Content'),
          actions: <Widget>[
            CupertinoDialogAction(child: Text('Yes')),
            CupertinoDialogAction(child: Text('No')),
          ],
        );
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return CupertinoPageScaffold(
      navigationBar: const CupertinoNavigationBar(
        middle: Text('Home'),
      ),
      child: Center(child: CupertinoButton(
        onPressed: () {
          Navigator.of(context).restorablePush(_dialogBuilder);
        },
        child: const Text('Open Dialog'),
      )),
    );
  }
}

See also:

Implementation

Future<T?> showCupertinoDialog<T>({
  required BuildContext context,
  required WidgetBuilder builder,
  String? barrierLabel,
  bool useRootNavigator = true,
  bool barrierDismissible = false,
  RouteSettings? routeSettings,
}) {
  assert(builder != null);
  assert(useRootNavigator != null);

  return Navigator.of(context, rootNavigator: useRootNavigator).push<T>(CupertinoDialogRoute<T>(
    builder: builder,
    context: context,
    barrierDismissible: barrierDismissible,
    barrierLabel: barrierLabel,
    barrierColor: CupertinoDynamicColor.resolve(_kModalBarrierColor, context),
    settings: routeSettings,
  ));
}