断言失败:/C:/Flutter/sdk/flutter/packages/flutter/lib/src/widgets/will_pop_scope.dart:135:12 _route == M

Posted

技术标签:

【中文标题】断言失败:/C:/Flutter/sdk/flutter/packages/flutter/lib/src/widgets/will_pop_scope.dart:135:12 _route == ModalRoute.of(context) is not true【英文标题】:Assertion failed: /C:/Flutter/sdk/flutter/packages/flutter/lib/src/widgets/will_pop_scope.dart:135:12 _route == ModalRoute.of(context) is not true 【发布时间】:2021-09-24 07:37:39 【问题描述】:

返回上一个屏幕时出错.. 我也得到了

在小部件树中检测到重复的 GlobalKey。

屏幕 A -> 屏幕 B ->屏幕 c 工作正常

但是当从屏幕 C 回来时 ->屏幕 A 我遇到了这样的问题

orden_management

class SideBarOrderManagement extends StatelessWidget 

  @override
  Widget build(BuildContext context) 
    return ListTile(
      tileColor: Colors.transparent,
      onTap: () 
        Get.toNamed("/orders");
      ,
      // icon
      title: Text("ordermanagement".tr,
          style: Theme.of(context).textTheme.subtitle1),
      leading: Icon(Icons.local_offer,color: Colors.grey,),

    );
  

OrdersMainController 代码:

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:get/get.dart';

import 'package:novadan_admin/global/models/endpoint/responsedata/nv_orders_response_data.dart';
import 'package:novadan_admin/modules/orders/orders_main/services/orders_main_service.dart';

class OrdersMainController extends GetxController 
  final formKey = GlobalKey<FormBuilderState>().obs;
  // Rx<GlobalKey<FormBuilderState>> formKey = GlobalKey<FormBuilderState>().obs;
  final mainFuture = Future.wait([]).obs;
  final ordersData = NvOrdersResponseData().obs;
  final ordersFuture = Future.value(NvOrdersResponseData()).obs;
  var page = 1.obs;
  var statusMessage = "".obs;

  @override
  void onInit() 
    super.onInit();
    getOrders();
    mainFuture.value = Future.wait([ordersFuture.value]);
  

  getOrders() 
    ordersFuture.value = orders(page: page.value);
  

  void getPage(int newPage) 
    page.value = newPage;
    getOrders();
    update();
  

  void getNextPage() 
    if ((ordersData.value.total! / ordersData.value.perPage!).round() !=
        page.value) 
      page.value += 1;
      getOrders();
      update();
    
  

  void getPreviousPage() 
    if (page.value != 1) 
      page.value -= 1;
      getOrders();
      update();
    
  

  void getFirstPage() 
    if (page.value != 1) 
      page.value = 1;
      getOrders();
      update();
    
  

  void getLastPage() 
    if (page.value !=
        (ordersData.value.total! / ordersData.value.perPage!).round()) 
      page.value =
          (ordersData.value.total! / ordersData.value.perPage!).round();
      getOrders();
      update();
    
  

头代码

import 'package:flutter/material.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:get/get.dart';
import 'package:novadan_admin/modules/orders/orders_main/controllers/orders_main_controller.dart';
import 'package:novadan_admin/modules/orders/orders_main/widgets/datatable/widgets/head/widgets/fields/dropdowns/buyercity_dropdown.dart';
import 'package:novadan_admin/modules/orders/orders_main/widgets/datatable/widgets/head/widgets/fields/dropdowns/cargo_dropdown.dart';
import 'package:novadan_admin/modules/orders/orders_main/widgets/datatable/widgets/head/widgets/fields/dropdowns/managers_dropdown.dart';
import 'package:novadan_admin/modules/orders/orders_main/widgets/datatable/widgets/head/widgets/fields/dropdowns/orderstatus_dropdown.dart';
import 'package:novadan_admin/modules/orders/orders_main/widgets/datatable/widgets/head/widgets/fields/dropdowns/paymentstatus_dropdown.dart';
import 'package:novadan_admin/modules/orders/orders_main/widgets/datatable/widgets/head/widgets/fields/dropdowns/sellercity_dropdown.dart';
import 'package:novadan_admin/modules/orders/orders_main/widgets/datatable/widgets/head/widgets/fields/dropdowns/sort_dropdown.dart';
import 'package:novadan_admin/modules/orders/orders_main/widgets/datatable/widgets/head/widgets/fields/dropdowns/sort_dropdown.dart';
import 'package:novadan_admin/modules/orders/orders_main/widgets/datatable/widgets/head/widgets/fields/dropdowns/users_dropdown.dart';
import 'package:novadan_admin/modules/orders/orders_main/widgets/datatable/widgets/head/widgets/fields/textfields/searchbar.dart';

class OrdersMainDataTableHead extends StatelessWidget 
  final OrdersMainController ordersMainController = Get.find();

  @override
  Widget build(BuildContext context) 
    final width = MediaQuery.of(context).size.width;

    return FormBuilder(
        key: ordersMainController.formKey.value,
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(
              "ordersmaintitle".tr,
              style: Theme.of(context).textTheme.subtitle1,
            ),
            SizedBox(height: 15),
            ElevatedButton(
              onPressed: () ,
              child: Text("clearfilter".tr, style: Theme.of(context).textTheme.button),
            ),
            SizedBox(height: 15),
            OrdersMainDataTableHeaderSearchBar(),
            SizedBox(
              height: 30,
            ),
            GridView.count(
                childAspectRatio: .9 / .2,
                mainAxisSpacing: 20,
                shrinkWrap: true,
                physics: NeverScrollableScrollPhysics(),
                crossAxisCount: width < 714
                    ? 1
                    : width < 1001
                        ? 2
                        : width < 1019
                            ? 1
                            : width < 1358
                                ? 2
                                : width < 1317
                                    ? 2
                                    : width < 1451
                                        ? 3
                                        : width < 1694
                                            ? 3
                                            : width < 1921
                                                ? 4
                                                : 1,
                children: <Widget>[
                  OrdersMainDataTableHeaderSortDropDown(),
                  OrdersMainDataTableHeaderOrderStatusDropDown(),
                  OrdersMainDataTableHeaderPaymentStatusDropDown(),
                  OrdersMainDataTableHeaderSellerCityDropDown(),
                  OrdersMainDataTableHeaderBuyerCityDropDown(),
                  OrdersMainDataTableHeaderCargoDropDown(),
                  OrdersMainDataTableHeaderManagersDropDown(),
                  OrdersMainDataTableHeaderUserDropDown(),
                ]),
          ],
        ));
  

错误屏幕

控制台屏幕

will_pop_scope.dart:135:12 代码

// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'framework.dart';
import 'navigator.dart';
import 'routes.dart';

/// Registers a callback to veto attempts by the user to dismiss the enclosing
/// [ModalRoute].
///
/// @tool snippet --template=stateful_widget
///
/// Whenever the back button is pressed, you will get a callback at [onWillPop],
/// which returns a [Future]. If the [Future] returns true, the screen is
/// popped.
///
/// ```dart
/// bool shouldPop = true;
/// @override
/// Widget build(BuildContext context) 
///   return WillPopScope (
///     onWillPop: () async 
///       return shouldPop;
///     ,
///     child: const Text('WillPopScope sample'),
///   );
/// 
/// ```
/// @end-tool
///
/// @tool dartpad --template=stateful_widget_material
/// ```dart
/// bool shouldPop = true;
/// @override
/// Widget build(BuildContext context) 
///   return WillPopScope(
///     onWillPop: () async 
///       return shouldPop;
///     ,
///     child: Scaffold(
///       appBar: AppBar(
///         title: const Text('Flutter WillPopScope demo'),
///       ),
///       body: Center(
///         child: Column(
///           mainAxisAlignment: MainAxisAlignment.center,
///           children: <Widget>[
///             OutlinedButton(
///               child: const Text('Push'),
///               onPressed: () 
///                 Navigator.of(context).push<void>(
///                   MaterialPageRoute<void>(
///                     builder: (BuildContext context) 
///                       return const MyStatefulWidget();
///                     ,
///                   ),
///                 );
///               ,
///             ),
///             OutlinedButton(
///               child: Text('shouldPop: $shouldPop'),
///               onPressed: () 
///                 setState(
///                   () 
///                     shouldPop = !shouldPop;
///                   ,
///                 );
///               ,
///             ),
///             const Text('Push to a new screen, then tap on shouldPop '
///                 'button to toggle its value. Press the back '
///                 'button in the appBar to check its behaviour '
///                 'for different values of shouldPop'),
///           ],
///         ),
///       ),
///     ),
///   );
/// 
/// ```
///
/// @end-tool
///
/// See also:
///
///  * [ModalRoute.addScopedWillPopCallback] and [ModalRoute.removeScopedWillPopCallback],
///    which this widget uses to register and unregister [onWillPop].
///  * [Form], which provides an `onWillPop` callback that enables the form
///    to veto a `pop` initiated by the app's back button.
///
class WillPopScope extends StatefulWidget 
  /// Creates a widget that registers a callback to veto attempts by the user to
  /// dismiss the enclosing [ModalRoute].
  ///
  /// The [child] argument must not be null.
  const WillPopScope(
    Key? key,
    required this.child,
    required this.onWillPop,
  ) : assert(child != null),
       super(key: key);

  /// The widget below this widget in the tree.
  ///
  /// @macro flutter.widgets.ProxyWidget.child
  final Widget child;

  /// Called to veto attempts by the user to dismiss the enclosing [ModalRoute].
  ///
  /// If the callback returns a Future that resolves to false, the enclosing
  /// route will not be popped.
  final WillPopCallback? onWillPop;

  @override
  State<WillPopScope> createState() => _WillPopScopeState();


class _WillPopScopeState extends State<WillPopScope> 
  ModalRoute<dynamic>? _route;

  @override
  void didChangeDependencies() 
    super.didChangeDependencies();
    if (widget.onWillPop != null)
      _route?.removeScopedWillPopCallback(widget.onWillPop!);
    _route = ModalRoute.of(context);
    if (widget.onWillPop != null)
      _route?.addScopedWillPopCallback(widget.onWillPop!);
  

  @override
  void didUpdateWidget(WillPopScope oldWidget) 
    super.didUpdateWidget(oldWidget);
    assert(**_route** == ModalRoute.of(context));
    if (widget.onWillPop != oldWidget.onWillPop && _route != null) 
      if (oldWidget.onWillPop != null)
        _route!.removeScopedWillPopCallback(oldWidget.onWillPop!);
      if (widget.onWillPop != null)
        _route!.addScopedWillPopCallback(widget.onWillPop!);
    
  

  @override
  void dispose() 
    if (widget.onWillPop != null)
      _route?.removeScopedWillPopCallback(widget.onWillPop!);
    super.dispose();
  

  @override
  Widget build(BuildContext context) => widget.child;

【问题讨论】:

【参考方案1】:

看看这是否可行,我只是遇到了这个问题,并通过弄乱找到了解决方案:Flutter Routing Issue and Duplicate GlobalKey

【讨论】:

您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center。

以上是关于断言失败:/C:/Flutter/sdk/flutter/packages/flutter/lib/src/widgets/will_pop_scope.dart:135:12 _route == M的主要内容,如果未能解决你的问题,请参考以下文章

findcontours 断言失败

UIWindowController 断言失败

[C#FluentAssertions在断言失败后继续

C# FluentAssertions 在断言失败后继续

选择器视图上的断言失败

更新uitableview时断言失败