AlertDialog without context in Flutter

前端 未结 4 1895
遥遥无期
遥遥无期 2021-02-02 12:50

I want to show an AlertDialog when a http get fails. The function showDialog (https://api.flutter.dev/flutter/material/showDialog.html) has the parameter \"@required BuildContex

4条回答
  •  后悔当初
    2021-02-02 13:27

    Solution without third-party libraries or storing BuildContext:

    final navigatorKey = GlobalKey();
    
    void main() => runApp(
      MaterialApp(
        home: HomePage(),
        navigatorKey: navigatorKey, // Setting a global key for navigator
      ),
    );
    
    class HomePage extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(),
          body: SafeArea(
            child: Center(
              child: Text('test')
            )
          ),
          floatingActionButton: FloatingActionButton(
            onPressed: showMyDialog, // Calling the function without providing it BuildContext
          ),
        );
      }
    }
    
    void showMyDialog() {
      showDialog(
        context: navigatorKey.currentContext,
        builder: (context) => Center(
          child: Material(
            color: Colors.transparent,
            child: Text('Hello'),
          ),
        )
      );
    }
    

    After setting a global key for navigator (navigatorKey parameter of MaterialApp class), its current state becomes accessible from any part of the code. We can pass its context to the showDialog function. Make sure not to use it before the first frame is built, otherwise the state will be null.

    Basically, dialogs are just another type of routes like MaterialPageRoute or CupertinoPageRoute - they are all derived from the ModalRoute class and their instances are pushed into NavigatorState. Context is only needed to get the current navigator's state. A new route can be pushed without having a context if we have a global navigator key:

    navigatorKey.currentState.push(route)
    

    Unfortunately, _DialogRoute class (...\flutter\lib\src\widgets\routes.dart) used in showDialog function is private and unaccessible, but you make your own dialog route class and push it into the navigator's stack.

    UPDATE: Navigator.of method has been updated and it's no longer needed to pass subtree context.

提交回复
热议问题