带有导航键而不是传递上下文的showDialog颤抖

时间:2019-03-15 18:18:19

标签: flutter

当前,它非常忙于显示应用程序中任何代码层的对话框,这仅仅是因为必须在其中传递上下文。因此,我想传递navigatorKey.currentContext(导航器键是传递给Material应用程序navigatorKey参数的全局键)以显示对话框。但是我得到了错误

“请求的导航器操作的上下文不包含导航器。用于从导航器推送或弹出路由的上下文必须是作为导航器小部件的后代的小部件的上下文。”

问题是showDialog在内部调用Navigator.of(context)并查找导航器的祖先,由于导航器本身是根,因此它当然会返回null。因此,它将不会找到导航器作为祖先。

有没有一种方法可以直接将导航器的状态/上下文传递给showDialog函数以显示对话框?或者,如果我们想从团体中显示对话框,是否有一种更简单的方法来显示对话框而不向其传递上下文?

4 个答案:

答案 0 :(得分:7)

我找到了一个简单的解决方案:

navigatorKey.currentState.overlay.context

我在保留navigatorKey的redux中间件中使用了此功能,并且希望在我每次分派特定操作时在应用程序中的任何位置全局显示对话框。

答案 1 :(得分:1)

您可以在此处使用InheritedWidget。将InheritedWidget用作拥有导航键的应用程序的根。然后,您可以传递任何context个子小部件以获取当前导航器状态。

示例:

InheritedWidget:

// Your InheritedWidget
class NavigatorStateFromKeyOrContext extends InheritedWidget {
  const NavigatorStateFromKeyOrContext({
    Key key,
    @required this.navigatorKey,
    @required Widget child,
  }) : super(key: key, child: child);

  final GlobalKey<NavigatorState> navigatorKey;

  static GlobalKey<NavigatorState> getKey(BuildContext context) {
    final NavigatorStateFromKeyOrContext provider =
        context.inheritFromWidgetOfExactType(NavigatorStateFromKeyOrContext);
    return provider.navigatorKey;
  }

  static NavigatorState of(BuildContext context) {
    NavigatorState state;
    try {
      state = Navigator.of(context);
    } catch (e) {
      // Assertion error thrown in debug mode, in release mode no errors are thrown
      print(e);
    }
    if (state != null) {
      // state can be null when context does not include a Navigator in release mode
      return state;
    }
    final NavigatorStateFromKeyOrContext provider =
        context.inheritFromWidgetOfExactType(NavigatorStateFromKeyOrContext);
    return provider.navigatorKey?.currentState;
  }

  @override
  bool updateShouldNotify(NavigatorStateFromKeyOrContext oldWidget) {
    return navigatorKey != oldWidget.navigatorKey;
  }
}

主屏幕:

// Your home screen
class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      navigatorKey: NavigatorStateFromKeyOrContext.getKey(context),
      home: InitPage(),
    );
  }
}

应用程序的根目录看起来像

final GlobalKey navigator = GlobalKey<NavigatorState>(debugLabel: 'AppNavigator');

runApp(
  NavigatorStateFromKeyOrContext(
    navigatorKey: navigator,
    child: HomePage(),
  ),
);

现在可以从应用程序中的任何位置传递任何上下文,以像NavigatorState一样

NavigatorStateFromKeyOrContext.of(context)

注意:这是我使用InheritedWidget时想到的一种方法,还有许多其他方法可以实现这一点,例如使用Singleton时,需要使用全局块来提供导航键,存储Redux商店中的导航键或任何其他全局状态管理解决方案等。

希望这会有所帮助!

答案 2 :(得分:0)

当前,我正在通过在util类中创建一个函数来显示对话框,该函数将上下文作为参数。

static void showAlertDialog(String title, String message, BuildContext context) { // flutter defined function showDialog( context: context, builder: (BuildContext context) { // return object of type Dialog return AlertDialog( title: new Text(title), content: new Text(message), actions: <Widget>[ // usually buttons at the bottom of the dialog new FlatButton( child: new Text("Close"), onPressed: () { Navigator.of(context).pop(); }, ), ], ); }, ); }

将以上功能用作: UtilClass. showAlertDialog("Title", "Message", context);

答案 3 :(得分:0)

由于此一项已合并: https://github.com/flutter/flutter/pull/58259

您可以使用:

char*