Flutter 中的多个导航器导致弹出问题 [英] Multiple navigators in Flutter causes problem with pop

查看:34
本文介绍了Flutter 中的多个导航器导致弹出问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用多个导航器的 Flutter 情况下苦苦挣扎.这里的概念是一个页面,它用自己的多页面流触发一个模态.在模态内一切都在迅速进行(导航推送/弹出正在工作),但如果模态被解除,它将删除最低导航器的每一页.我看过 https://stackoverflow.com/a/51589338 的例子,但我可能在这里遗漏了一些东西.

I'm struggling in a Flutter situation with multiple navigators. Concept here is a page which triggers a modal with his own flow of multiple pages. Inside the modal everything is going swiftly (navigation pushes/pops are working), but if the modal is dismissed it removes every page of the lowest navigator. I've looked at the example of https://stackoverflow.com/a/51589338, but I'm probably missing something here.

页面内有一个包装 Widget,它是应用程序的根目录.

There's a wrapper Widget inside a page which is the root of the application.

class Wrapper extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      child: Padding(
        padding: EdgeInsets.only(top: 10, bottom: 20),
        child: FlatButton(
          child: Padding(
            padding: EdgeInsets.symmetric(vertical: 5),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.center,
              crossAxisAlignment: CrossAxisAlignment.center,
              children: [
                Text(
                  'Open modal',
                ),
              ],
            ),
          ),
          onPressed: () {
            Navigator.of(context).push(
              MaterialPageRoute(
                settings: RouteSettings(name: '/modal'),
                builder: (context) => Modal(),
              ),
            );
          },
        ),
      ),
    );
  }
}

模态使用自己的导航器启动 Scaffold 来处理自己的流程.

The modal initiates a Scaffold with his own navigator to handle its own flow.

class Modal extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: new Navigator(
        initialRoute: FirstModalPage.route().toString(),
        onGenerateRoute: (routeSettings) {
          final path = routeSettings.name;
          if (path == '/secondmodalpage') {
            return MaterialPageRoute(
              settings: routeSettings,
              builder: (_) => SecondModalPage(),
            );
          }

          return new MaterialPageRoute(
            settings: routeSettings,
            builder: (_) => FirstModalPage(),
          );
        },
      ),
    );
  }
}

模态内的页面下面有一个关闭按钮,它应该从根导航器中删除模态.但是出于某种原因,如果我调用 pop() 它将从小部件树中删除所有页面.而 popUntil((route) => route.isFirst) 根本不做任何事情.如果我通过 Widget Inspector 查看小部件,它确实会说 Wrapper 和 Modal 处于同一级别.

The pages inside the modal are below with a close button which should remove the modal from the root navigator. But for some reason if I call pop() it removes all pages from the widget tree. And popUntil((route) => route.isFirst) doesn't do anything at all. If I'm looking at the widget via the Widget Inspector it does say that the Wrapper and Modal are on the same level.

class FirstModalPage extends StatelessWidget {
  static Route route() {
    return MaterialPageRoute<void>(builder: (_) => FirstModalPage());
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        mainAxisSize: MainAxisSize.max,
        children: <Widget>[
          Padding(
            padding: EdgeInsets.only(
              top: 30,
              right: 20,
              bottom: 10,
              left: 20,
            ),
            child: Row(
              mainAxisSize: MainAxisSize.max,
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                GestureDetector(
                  behavior: HitTestBehavior.translucent,
                  onTap: () {
                    if (Navigator.of(context).canPop()) {
                      Navigator.of(context).pop();
                    }
                  },
                  child: Text('Back'),
                ),
                Text(
                  'First modal page title'
                ),
                GestureDetector(
                  behavior: HitTestBehavior.translucent,
                  onTap: () {
                    Navigator.of(context, rootNavigator: true).popUntil(
                      (route) => route.isFirst,
                    );
                  },
                  child: Text('Close'),
                ),
              ],
            ),
          ),
          FlatButton(
            onPressed: () {
              Navigator.of(context).push(
                MaterialPageRoute(builder: (context) => SecondModalPage()),
              );
            },
            child: Text(
              'Second modal page'
            ),
          ),
        ],
      ),
    );
  }
}

推荐答案

您需要使用 Navigator 键来密切关注您需要使用哪个 Navigator 执行操作.

You'd need to use a Navigator key to keep tab on which Navigator you need to do an action with.

final _mainNavigatorKey = GlobalKey<NavigatorState>();

Navigator(
  key: _mainNavigatorKey,
  ...
),

要使用导航键,可以调用_mainNavigatorKey.currentState.pop();

To use the Navigator Key, you can call _mainNavigatorKey.currentState.pop();

这篇关于Flutter 中的多个导航器导致弹出问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆