dart - 导航器弹出错误直到 : "!_debugLocked' : is not true."

标签 dart flutter navigator

当通过单击 showBottomSheet 弹出导航到另一个屏幕时,通过以下代码抛出此错误。我不明白为什么会这样。

class _CheckoutButtonState extends State<_CheckoutButton> {
  final GlobalKey<ScaffoldState> _globalKey = GlobalKey();
  final DateTime deliveryTime = DateTime.now().add(Duration(minutes: 30));

  final double deliveryPrice = 5.00;

  @override
  Widget build(BuildContext context) {
    SubscriptionService subscriptionService =
        Provider.of<SubscriptionService>(context);
    CheckoutService checkoutService = Provider.of<CheckoutService>(context);
    return Container(
      height: 48.0,
      width: MediaQuery.of(context).size.width * 0.75,
      child: StreamBuilder(
        stream: subscriptionService.subscription$,
        builder: (_, AsyncSnapshot<Subscription> snapshot) {
          if (!snapshot.hasData) {
            return Text("CHECKOUT");
          }
          final Subscription subscription = snapshot.data;
          final List<Order> orders = subscription.orders;
          final Package package = subscription.package;
          num discount = _getDiscount(package);
          num price = _totalPriceOf(orders, discount);
          return StreamBuilder<bool>(
              stream: checkoutService.loading$,
              initialData: false,
              builder: (context, snapshot) {
                bool loading = snapshot.data;
                return ExtendedFloatingActionButton(
                  loading: loading,
                  disabled: loading,
                  action: () async {
                    checkoutService.setLoadingStatus(true);
                    final subscription =
                        await Provider.of<SubscriptionService>(context)
                            .subscription$
                            .first;
                    try {
                      await CloudFunctions.instance.call(
                          functionName: 'createSubscription',
                          parameters: subscription.toJSON);
                      final bottomSheet =
                          _globalKey.currentState.showBottomSheet(
                        (context) {
                          return Container(
                            width: MediaQuery.of(context).size.width,
                            decoration: BoxDecoration(
                              gradient: LinearGradient(
                                begin: Alignment.topCenter,
                                end: Alignment.bottomCenter,
                                colors: [
                                  Theme.of(context).scaffoldBackgroundColor,
                                  Theme.of(context).primaryColor,
                                  Theme.of(context).primaryColor,
                                ],
                                stops: [-1.0, 0.5, 1.0],
                              ),
                            ),
                            child: Column(
                              children: <Widget>[
                                Expanded(
                                  child: Column(
                                    mainAxisAlignment: MainAxisAlignment.center,
                                    children: <Widget>[
                                      Padding(
                                        padding:
                                            const EdgeInsets.only(bottom: 16.0),
                                        child: Text(
                                          "Thank you for your order",
                                          textAlign: TextAlign.center,
                                          style: Theme.of(context)
                                              .textTheme
                                              .display1,
                                        ),
                                      ),
                                      SvgPicture.asset(
                                        'assets/images/thumb.svg',
                                        height: 120.0,
                                        width: 100.0,
                                      )
                                      // CircleAvatar(
                                      // radius: 40.0,
                                      // backgroundColor: Colors.transparent,
                                      // child: Icon(
                                      // Icons.check,
                                      // color: Theme.of(context)
                                      // .textTheme
                                      // .display1
                                      // .color,
                                      // size: 80.0,
                                      // ),
                                      // ),
                                    ],
                                  ),
                                ),
                                Container(
                                  width:
                                      MediaQuery.of(context).size.width * 0.9,
                                  height: 72.0,
                                  padding: EdgeInsets.only(bottom: 24),
                                  child: ExtendedFloatingActionButton(
                                    text: "ORDER DETAILS",
                                    action: () {
                                      Navigator.of(context).pop();
                                    },
                                  ),
                                ),
                              ],
                            ),
                          );
                        },
                      );
                      bottomSheet.closed.then((v) {
                        Navigator.of(context)
                            .popUntil((r) => r.settings.isInitialRoute);
                      });
                    } catch (e) {
                      print(e);
                      final snackBar =
                          SnackBar(content: Text('Something went wrong!'));
                      Scaffold.of(context).showSnackBar(snackBar);
                    }
                  },
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: <Widget>[
                      Text(
                        "CHECKOUT ",
                        style: Theme.of(context)
                            .textTheme
                            .display4
                            .copyWith(color: Colors.white),
                      ),
                      Text(
                        "EGP " +
                            (price + (orders.length * deliveryPrice))
                                .toStringAsFixed(2),
                        style: Theme.of(context)
                            .textTheme
                            .display4
                            .copyWith(color: Theme.of(context).primaryColor),
                      ),
                    ],
                  ),
                );
              });
        },
      ),
    );
  }

  num _totalPriceOf(List<Order> orders, num discount) {
    num price = 0;
    orders.forEach((Order order) {
      List<Product> products = order.products;
      products.forEach((Product product) {
        price = price + product.price;
      });
    });
    num priceAfterDiscount = price * (1 - (discount / 100));
    return priceAfterDiscount;
  }

  num _getDiscount(Package package) {
    if (package == null) {
      return 0;
    } else {
      return package.discount;
    }
  }
}

错误:

>══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
I/flutter (24830): The following assertion was thrown building Navigator-[GlobalObjectKey<NavigatorState>
I/flutter (24830): _WidgetsAppState#90d1f](dirty, state: NavigatorState#6b2b6(tickers: tracking 1 ticker)):
I/flutter (24830): 'package:flutter/src/widgets/navigator.dart': Failed assertion: line 1995 pos 12: '!_debugLocked':
I/flutter (24830): is not true.
I/flutter (24830): Either the assertion indicates an error in the framework itself, or we should provide substantially
I/flutter (24830): more information in this error message to help you determine and fix the underlying cause.
I/flutter (24830): In either case, please report this assertion by filing a bug on GitHub:
I/flutter (24830):   https://github.com/flutter/flutter/issues/new?template=BUG.md
I/flutter (24830): When the exception was thrown, this was the stack:

最佳答案

我不会直接给你答案,而是会向你介绍一下我看到这个问题时的想法,希望它能在未来对你有所帮助。

让我们看一下断言。它说 Failed assertion: line 1995 pos 12: '!_debugLocked': I/flutter (24830): is not true.。嗯,有意思。让我们看一下那行代码。

assert(!_debugLocked);

好吧,这并没有给我更多的信息,让我们看看变量。

bool _debugLocked = false; // used to prevent re-entrant calls to push, pop, and friends

这样更好。它用于防止对 push、pop 等的重入调用(这意味着它不希望您在对“push”、“pop”的调用中调用“push”、“pop”等)。因此,让我们将其追溯到您的代码。

这似乎是罪魁祸首:

bottomSheet.closed.then((v) {
  Navigator.of(context)
    .popUntil((r) => r.settings.isInitialRoute);
});

我将在这里跳过一步并改用演绎推理 - 我打赌封闭的 future 在 pop 期间结束。如果您愿意,请继续阅读代码以确认这一点。

因此,如果问题是我们从 pop 函数中调用 pop,我们需要找出一种方法将对 pop 的调用推迟到 pop 完成之后。

这变得非常简单 - 有两种方法可以做到这一点。简单的方法是只使用零延迟的延迟 future ,一旦当前调用堆栈返回到事件循环,dart 将尽快安排调用:

Future.delayed(Duration.zero, () {
  Navigator. ...
});

另一种更 flutter-y 的方法是在当前构建/渲染周期完成后使用 Scheduler 安排调用:

SchedulerBinding.instance.addPostFrameCallback((_) {
  Navigator. ...
});

无论哪种方式都应该可以消除您遇到的问题。

另一个选项也是可能的 - 在你调用 pop 的 ExtendedFloatingActionButton 中:

ExtendedFloatingActionButton(
 text: "ORDER DETAILS",
  action: () {
    Navigator.of(context).pop();
  },
),

您可以改为简单地调用 Navigator.of(context).popUntil...。这将消除在调用 bottomSheet.closed 之后执行任何操作的需要。但是,根据您在逻辑中可能需要或不需要做的任何其他事情,这可能并不理想(我绝对可以看到让底部工作表引发对页面主要部分的更改以及您为什么这样做的问题试图在页面的逻辑中实现这一点)。

此外,当您编写代码时,我强烈建议将它分成小部件 - 例如底部工作表应该是它自己的小部件。您在构建函数中包含的内容越多,就越难遵循,它实际上也会对性能产生影响。您还应该尽可能避免使用 GlobalKey 实例 - 如果对象(或回调)仅通过几层,您通常可以向下传递对象(或回调),使用 .of(context) 模式,或使用继承的小部件。

关于dart - 导航器弹出错误直到 : "!_debugLocked' : is not true.",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55618717/

相关文章:

android - NoSuchMethodError : The method 'of' was called on null 错误

android - Flutter/Dart Android应用程式NoSuchMethodError

Firebase 列表未在设置状态下更新

dart - 如何在我的 Flutter 应用程序中重置基本路由 - 即弹出任何路由并使用 Navigator 将其替换为新路由

mobile - Flutter 无法更改路由,因为 PopupMenuButton 未定义名称上下文如何解决?

objective-c - 如何使用 Dart ffi 表示具有 int 和字符串声明的 ObjC 枚举 AVAudioSessionPortOverride?

flutter - 是否有一个库可以在 flutter 应用中绘制音频波形

flutter - Android SDK 缺少命令行工具

time - highstock - 添加/删除系列后导航器时间范围不会更新

logging - flutter :记录器