【问题标题】:Flutter Navigation push() and pop(), filling up the stack?Flutter Navigation push() 和 pop(),把栈填满了?
【发布时间】:2019-02-06 06:08:33
【问题描述】:

在 Flutter 中构建一个应用程序,我想使用 Navigation Drawer 并添加了一些 FlatButtons。 每个FlatButton 都有一个onPressed() 方法,我在其中将Navigator.push() 移动到所需的页面,效果很好。

我想知道随着时间的推移这是否会填满内存,因为我总是在推送但从不从堆栈中弹出页面。 总是将Navigator.pop()Navigator.push() 连续组合起来似乎有点奇怪,而且与良好做法相去甚远。

也许有人可以告诉我正确的方法。

【问题讨论】:

    标签: dart flutter


    【解决方案1】:

    这确实会导致潜在的内存问题。要解决此问题,您可以弹出不需要的路由。您还可以添加自定义NavigatorObserver 以添加历史限制。

    示例:

    class HistoryLimit extends NavigatorObserver {
      final int limit;
      final history = <Route>[];
    
      HistoryLimit([this.limit = 42]);
    
    
      @override
      void didReplace({Route<dynamic> newRoute, Route<dynamic> oldRoute}) {
        final index = history.indexOf(oldRoute);
        history[index] = newRoute;
      }
    
    
      @override
      void didPush(Route route, Route previousRoute) {
        history.add(route);
        if (history.length >= limit) {
          this.navigator.removeRoute(history.first);
        }
      }
    
      @override
      void didPop(Route route, Route previousRoute) {
        history.remove(route);
      }
    
      @override
      void didRemove(Route route, Route previousRoute) {
        history.remove(route);
      }
    }
    

    在此处添加您使用的:

    MaterialApp(
      navigatorObservers: [
       HistoryLimit(10) 
      ],
      ...
    )
    

    【讨论】:

    • 这段代码导致我的导航在点击 10 次后停止工作。知道有什么问题吗? Flutter 告诉我:[ERROR:flutter/lib/ui/ui_dart_state.cc(148)] Unhandled Exception: 'package:flutter/src/widgets/navigator.dart': Failed assertion: line 2124 pos 12: '!_debugLocked': is not true. 在 navigator.dart 中显示:assert(() { debugPredictedWouldPop = !route.willHandlePopInternally; return true; }()); 运行此方法后,导航不想再推送了。
    【解决方案2】:

    当您希望后退按钮导航到上一条路线时,请使用 Navigator.pop()。在这种情况下,是的,堆栈不断填满。

    还有其他类似的方法

    用新的路线替换当前路线。 这样一来,您就不能使用 Android 后退按钮来导航回之前的每条路线。

    【讨论】:

    • 你也可以添加某种历史限制
    • 不,我正在考虑一个自定义 NavigatorObserver,它会在推送时删除旧路由
    • 好的,基本上他现在在做什么,但更聪明一点。
    【解决方案3】:

    你试过了吗

    Navigator
            .of(context)
            .pushReplacement(...
    
    
    ?
    

    【讨论】:

      【解决方案4】:

      除了@Remi 的回答。 如果这个this.navigator.removeRoute(history.first); 抛出错误:

      !_debugLocked
      is not true
      

      延迟下一个导航器操作

        @override
        void didPush(Route route, Route previousRoute) {
          history.add(route);
          if (history.length >= limit) {
            Future.delayed(Duration.zero, () {
              this.navigator.removeRoute(history.first);
            });    
          }
        }
      

      Navigator 不允许在对“push”、“pop”的调用中进行“push”、“pop”等。

      【讨论】:

        猜你喜欢
        • 2016-08-16
        • 2013-04-20
        • 2010-09-30
        • 2023-04-01
        • 2011-05-04
        • 2020-11-26
        • 2014-08-12
        • 2020-09-08
        • 1970-01-01
        相关资源
        最近更新 更多