Flutter Navigator.popUntil断言_debugLocked失败。怎么了?

时间:2019-10-01 10:44:06

标签: flutter flutter-navigation

^ ^ ^^ ^不!此问题没有有答案! ^ ^ ^ ^ ^

我遇到Navigator.popUntil的问题。我编写了一个小型演示应用程序以显示正在发生的事情。在我将其发布为错误之前,我使用popUntil错了吗?

调用popUntil显示

enter image description here

看起来有些东西在锁定导航器(设置_debugLocked)并且没有释放它。

下面的main.dart :(可以粘贴到Flutter演示应用程序中)

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Routing Test Page'),
      onGenerateRoute: (RouteSettings settings) {
        switch (settings.name) {
          case '/':
            return MaterialPageRoute(
              builder: (_) => MyHomePage(title: 'Home Page',),
              settings: settings,
            );
          case '/home':
            return MaterialPageRoute(
              builder: (_) => MyHomePage(title: 'Home Page',),
              settings: settings,
            );
          case '/middlepage':
            return MaterialPageRoute(
              builder: (_) => MiddlePage(),
              settings: settings,
            );
          case '/bottompage':
            return MaterialPageRoute(
              builder: (_) => BottomBage(),
              settings: settings,
            );
          default:
            return null;
        }
      },
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'Home Page',
            ),
            OutlineButton(
              child: Text('push MiddlePage()'),
              onPressed: () => Navigator.push(
                context,
                MaterialPageRoute(builder: (context) => (MiddlePage())),
              ),
            ),
            OutlineButton(
              child: Text('pushNamed ''/middlepage'''),
              onPressed: () => Navigator.pushNamed(context, '/middlepage'),
            ),
          ],
        ),
      ),
    );
  }
}

class MiddlePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Middle Page'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'Middle Page',style: TextStyle(fontWeight: FontWeight.bold)
            ),
            OutlineButton(
              child: Text('push BottomPage()'),
              onPressed: () => Navigator.push(
                context,
                MaterialPageRoute(builder: (context) => (BottomBage())),
              ),
            ),
            OutlineButton(
              child: Text('pushNamed ''/bottompage'''),
              onPressed: () => Navigator.pushNamed(context, '/bottompage'),
            ),
            OutlineButton(
                child: Text('pop'), onPressed: () => Navigator.pop(context)),
            OutlineButton(
                child: Text('popUntil ''/home'''),
                onPressed: () =>
                    Navigator.popUntil(context, ModalRoute.withName('/home'))),
          ],
        ),
      ),
    );
  }
}

class BottomBage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Bottom page'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'Bottom Page', style: TextStyle(fontWeight: FontWeight.bold),
            ),
            OutlineButton(
              child: Text('push ''home'''),
              onPressed: () =>
                  Navigator.pushNamed(context, '/home'),
            ),
            OutlineButton(
                child: Text('pop'),
                onPressed: () =>
                    Navigator.pop(context)),

            OutlineButton(
              child: Text('popUntil ''/home'''),
              onPressed: () =>
                  Navigator.popUntil(context, ModalRoute.withName('/home')),
            ),
            OutlineButton(
              child: Text('popUntil ''/home'' (with Are You Sure box)) '),
              onPressed: () async {
                try {
                  if (await _areYouSureDialog(context)) {
                    Navigator.popUntil(context, ModalRoute.withName('/home'));
                  }
                } catch (e) {
                  debugPrint("exception: $e");
                }
              },
            ),
          ],
        ),
      ),
    );
  }
}

Future<bool> _areYouSureDialog(BuildContext context) async {
  return await showDialog<bool>(
        context: context,
        builder: (BuildContext context) {
          return AlertDialog(
            title: const Text('Pop back?'),
            content: const Text('Are you sure?'),
            actions: <Widget>[
              FlatButton(
                child: const Text('YES'),
                onPressed: () {
                  Navigator.of(context).pop(true);
                },
              ),
              FlatButton(
                child: const Text('NO'),
                onPressed: () {
                  Navigator.of(context).pop(false);
                },
              ),
            ],
          );
        },
      ) ??
      false;
}

1 个答案:

答案 0 :(得分:1)

我重新审理了你的案子。每当我们想从任何地方弹出导航到主屏幕(根目录)时,都有以下几种方法:

1。使用.isFirst方法:

Navigator.of(context).popUntil((route) => route.isFirst);
  1. 使用defaultRouteName

Navigator.popUntil(context, ModalRoute.withName(Navigator.defaultRouteName));

通过context首先提供route,将确保导航始终弹出到默认位置。

您可以尝试使用任何一种方法。我结束时进行了测试,效果很好。

希望这能回答您的问题。