颤动删除所有路线

chr*_*don 38 dart flutter

我想开发一个注销按钮,它会将我发送到路由中的日志并从中删除所有其他路由Navigator.该文档似乎没有解释如何创建RoutePredicate或具有任何类型的removeAll函数.

chr*_*don 109

我能够使用以下代码完成此任务:

Navigator.of(context)
    .pushNamedAndRemoveUntil('/login', (Route<dynamic> route) => false);
Run Code Online (Sandbox Code Playgroud)

这里的秘密是使用始终返回false的RoutePredicate (Route<dynamic> route) => false.在这种情况下,除了/login我推送的新路由之外,它将删除所有路由.

  • @Developine我知道已经很晚了,但如果其他人需要传递参数,可以通过这种方式完成`Navigator.of(context).pushNamedAndRemoveUntil('/login', (Route&lt;dynamic&gt;route) =&gt; false,arguments : {“键”:“值”});` (4认同)
  • 即使使用此功能后,我仍然有打开的实例。还有其他解决方案来推动屏幕并删除堆栈的其余部分吗? (3认同)
  • 我们怎样才能用这种方法传递参数呢? (2认同)

小智 25

另一种解决方案是使用pushAndRemoveUntil(). 要删除所有其他路线,请使用ModalRoute.withName('/')

Navigator.pushAndRemoveUntil(
    context,   
    MaterialPageRoute(builder: (BuildContext context) => Login()), 
    ModalRoute.withName('/')
);
Run Code Online (Sandbox Code Playgroud)

参考:https : //api.flutter.dev/flutter/widgets/NavigatorState/pushAndRemoveUntil.html


Vol*_*vus 20

如果您想返回特定屏幕并且不使用命名路由器,则可以使用下一种方法

例子:

Navigator.pushAndRemoveUntil(context,
                  MaterialPageRoute(builder: (BuildContext context) => SingleShowPage()),
                  (Route<dynamic> route) => route is HomePage
              );
Run Code Online (Sandbox Code Playgroud)

使用route is HomePage,您可以检查小部件的名称。

  • (Route&lt;dynamic&gt;route) =&gt;route.isFirst) 如果有人想要删除直到第一个路由。 (2认同)

Moh*_*mel 19

使用 popUntil 如下

Navigator.popUntil(context, (route) => route.isFirst);


Kel*_*oto 13

如果您使用的是 namedRoutes,您可以简单地执行此操作:

Navigator.pushNamedAndRemoveUntil(context, "/login", (Route<dynamic> route) => false);
Run Code Online (Sandbox Code Playgroud)

其中“/login”是您要推送到路由堆栈上的路由。

注意 :

此语句删除堆栈中的所有路由,并使推送的路由成为根。


小智 11

我可以使用以下代码段进行操作:

 Navigator.of(context).pushAndRemoveUntil(MaterialPageRoute(builder: (context) =>
    LoginScreen()), (Route<dynamic> route) => false),
Run Code Online (Sandbox Code Playgroud)

如果要删除所推送的路线下方的所有路线,RoutePredicate始终返回false,例如(Route route)=> false

  • 如果你想在导航页面上发送参数,那么你可以使用“Navigator.pushNamedAndRemoveUntil(context, "/newRouteName", (r) =&gt; false,argument: { "arg_1": firstArgument, "arg_2": secondaryArgument });" (2认同)

Ale*_*Pad 9

就我而言,我有这幅画 第 1 页(主) -> 第 2 页 -> 第 3 页 -> 第 4 页。

当我必须转到第 4 页时,返回的第 2 页和第 3 页不必出现,但我必须再次转到第 1 页。此时,转到第 4 页,我执行了以下操作:

Navigator.pushAndRemoveUntil(
              context,
              MaterialPageRoute(
                  builder: (BuildContext context) =>
                      Workout()),
             (Route<dynamic> route) => route.isFirst);
Run Code Online (Sandbox Code Playgroud)

说明是:转到第 4 页(锻炼)并删除所有之前的页面(最多 1 页),即(主要)。

在您的情况下,可以从任何内容切换到登录,然后:

Navigator.pushAndRemoveUntil(
              context,
              MaterialPageRoute(
                  builder: (BuildContext context) =>
                      Login()),
             (Route<dynamic> route) => false);
Run Code Online (Sandbox Code Playgroud)

就是去登录,把之前的所有页面都去掉,因为有一个false。


mah*_*mnj 8

我不知道为什么没有人提到使用SchedularBindingInstance的解决方案,虽然聚会有点晚,但我认为这将是正确的方法,最初在这里回答

SchedulerBinding.instance.addPostFrameCallback((_) async {
   Navigator.of(context).pushNamedAndRemoveUntil(
      '/login',
      (Route<dynamic> route) => false);
});
Run Code Online (Sandbox Code Playgroud)

上面的代码删除了所有到“/login”的路由和导航,这也确保在通过调度回调导航到新路由之前渲染所有帧


nle*_*lie 7

另一种选择是 popUntil()

Navigator.of(context).popUntil(ModalRoute.withName('/root'));
Run Code Online (Sandbox Code Playgroud)

这将弹出所有路线,直到您返回指定的路线。


小智 7

不确定我这样做是否正确

但这适合我的用例,直到由根小部件弹出

void popUntilRoot({Object result}) {
    if (Navigator.of(context).canPop()) {
      pop();
      popUntilRoot();
    }
}
Run Code Online (Sandbox Code Playgroud)


Moh*_*our 7

就我而言,这个解决方案有效:

Navigator.pushNamedAndRemoveUntil(" The Route you want to go to " , (Route route) => false);
Run Code Online (Sandbox Code Playgroud)


roc*_*tar 6

这对我有用。实际上,我正在使用bloc,但我的问题是登录屏幕 bloc。注销后没有更新。它保存了以前的模型数据。甚至,我输入了错误的条目它要进入主屏幕。

步骤1:

Navigator.of(context).pushNamedAndRemoveUntil(
        UIData.initialRoute, (Route<dynamic> route) => false);
Run Code Online (Sandbox Code Playgroud)

在哪里, UIData.initialRoute = "/" or "/login"

第2步:

它正在努力刷新屏幕。如果您正在与 Bloc 合作,那么它将非常有帮助。

runApp(MyApp());
Run Code Online (Sandbox Code Playgroud)

在哪里, MyApp() is the root class.

根类(即MyApp)代码

class MyApp extends StatelessWidget {

  final materialApp = Provider(
      child: MaterialApp(
          title: UIData.appName,
          theme: ThemeData(accentColor: UIColor().getAppbarColor(),
            fontFamily: UIData.quickFont,
          ),
          debugShowCheckedModeBanner: false,
          //home: SplashScreen(),
          initialRoute: UIData.initialRoute,
          routes: {
            UIData.initialRoute: (context) => SplashScreen(),
            UIData.loginRoute: (context) => LoginScreen(),
            UIData.homeRoute: (context) => HomeScreen(),
          },
          onUnknownRoute: (RouteSettings rs) => new MaterialPageRoute(
              builder: (context) => new NotFoundPage(
                appTitle: UIData.coming_soon,
                icon: FontAwesomeIcons.solidSmile,
                title: UIData.coming_soon,
                message: "Under Development",
                iconColor: Colors.green,
              )
          )));

  @override
  Widget build(BuildContext context) {
    return materialApp;
  }
}

void main() => runApp(MyApp());
Run Code Online (Sandbox Code Playgroud)

这是我的注销方法,

void logout() async {
    SharedPreferences preferences = await SharedPreferences.getInstance();
    preferences.clear();

    // TODO: we can use UIData.loginRoute instead of UIData.initialRoute
    Navigator.of(context).pushNamedAndRemoveUntil(
        UIData.initialRoute, (Route<dynamic> route) => false);
    //TODO: It's working as refresh the screen
    runApp(MyApp());
  }
Run Code Online (Sandbox Code Playgroud)