在导航器弹出窗口上引发错误,直到:“!_debugLocked':不正确。”

Aya*_*isy 3 navigator dart flutter

通过单击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;
    }
  }
}

Run Code Online (Sandbox Code Playgroud)

错误:

??? 小工具图书馆的例外情况???????????????????????????????????????????????? ??????????????? I / flutter(24830):构建Navigator- [GlobalObjectKey I / flutter(24830):_WidgetsAppState#90d1f](脏,状态:NavigatorState#6b2b6(股票代码:跟踪1个股票代码))时引发了以下断言:I / flutter(24830) ):'package:flutter / src / widgets / navigator.dart':失败的断言:第1995行pos 12:'!_debugLocked':I / flutter(24830):不正确。I / flutter(24830):要么断言表明框架本身有错误,要么我们应该提供实质性的I / flutter(24830):此错误消息中的更多信息可帮助您确定和解决根本原因。I / flutter(24830):无论哪种情况,请通过在GitHub上提交错误来报告此断言:I / flutter(24830): https://github.com/flutter/flutter/issues/new?template=BUG.md I / flutter(24830):引发异常时,这是堆栈:

rmt*_*zie 16

我将不带给您直接答案,而是带您了解问题时的想法,以期将来对您有所帮助。

让我们看一下断言。它说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);
});
Run Code Online (Sandbox Code Playgroud)

我将在这里跳过步骤,而是使用演绎推理-我敢打赌,封闭的未来会在期间完成pop。如果愿意,请继续阅读代码以确认。

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

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

Future.delayed(Duration.zero, () {
  Navigator. ...
});
Run Code Online (Sandbox Code Playgroud)

另一种更加扑朔迷离的方式是在当前的构建/渲染周期完成后,使用调度程序来调度调用:

SchedulerBinding.instance.addPostFrameCallback((_) {
  Navigator. ...
});
Run Code Online (Sandbox Code Playgroud)

两种方法都可以消除您遇到的问题。

不过,另一个选项也是可能的-在ExtendedPloatingActionButton中,您将pop称为:

ExtendedFloatingActionButton(
 text: "ORDER DETAILS",
  action: () {
    Navigator.of(context).pop();
  },
),
Run Code Online (Sandbox Code Playgroud)

您可以直接致电Navigator.of(context).popUntil...。这将消除在调用bottomSheet.closed之后执行任何操作的需要。但是,根据您逻辑中可能需要做或不需要做的其他事情,这可能不是理想的选择(我可以肯定地看到了问题,底页导致了页面主要部分的更改,以及为什么要做试图做到这一点在页面的逻辑)。

另外,在编写代码时,我强烈建议将其分成小部件-例如,底页应该是其自己的小部件。构建功能越多,遵循起来就越困难,并且实际上也会对性能产生影响。您还应该避免使用GlobalKey实例-通常,如果仅通过几层,则可以向下传递对象(或回调),使用.of(context)模式或使用继承的小部件。

  • 是的,非常好的答案,更多的是关于如何解决问题而不仅仅是解决方案。它确实帮助我找到了需要放入 SchedulerBinding() 的区域。谢谢! (9认同)
  • 感人的!非常详细且一致的推动学习的方式,而不是简单地给你糖果:) 谢谢@rmtmckenzie (3认同)

s k*_*s k 15

对于那些Navigator在构建过程中调用 的人。我发现它会间歇性地在debugLocked

我通过包装避免了这个问题addPostFrameCallback

WidgetsBinding.instance.addPostFrameCallback((_) {
  Navigator.pushReplacement(context, MaterialPageRoute(builder: (_) => MyPage()));
});
Run Code Online (Sandbox Code Playgroud)

  • 我可以保证,作为 flutter 的初学者,我不知道该把它放在哪里。 (11认同)

Tas*_*hin 9

添加一些延迟然后尝试这样做您的问题将得到解决:

Future.delayed(const Duration(milliseconds: 500), () {
    setState(() {
      Navigator.of(context).pushAndRemoveUntil(
        MaterialPageRoute(builder: (context) => SetCategory()),
        (route) => false);
    });
  });
Run Code Online (Sandbox Code Playgroud)

  • 不漂亮,但有时这是唯一的解决方案 (2认同)