颤动删除所有路线

时间:2017-08-25 20:59:45

标签: dart flutter

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

13 个答案:

答案 0 :(得分:65)

我能够通过以下代码完成此任务:

Navigator.of(context)
    .pushNamedAndRemoveUntil('/login', (Route<dynamic> route) => false);

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

答案 1 :(得分:11)

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

示例:

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

使用路由为首页,您可以检查小部件的名称。

答案 2 :(得分:5)

如果您使用namedRoutes,则可以通过以下简单方式完成此操作:

Navigator.pushNamedAndRemoveUntil(context, "/login", (Route<dynamic> route) => false);

“ /登录” 是要在路由堆栈中推送的路由。

请注意:

此语句删除堆栈中的所有路由,并将被压入的路由设为根。

答案 3 :(得分:4)

我不知道为什么没有人提到使用SchedularBindingInstance的解决方案,但是晚了一点,我认为这原本是answered here的正确方法

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

上面的代码将所有路由和导航项都删除为“ / login”,这还可以确保通过调度回调导航到新路由之前,所有帧均已渲染

答案 4 :(得分:3)

另一种选择是popUntil()

Navigator.of(context).popUntil(ModalRoute.withName('/root'));

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

答案 5 :(得分:2)

这对我有用。实际上,我与 bloc 一起工作,但我的问题是登录屏幕块。注销后未更新。它保存了以前的模型数据。甚至,我输入了错误的条目,也就是进入主屏幕。

第1步:

Navigator.of(context).pushNamedAndRemoveUntil(
        UIData.initialRoute, (Route<dynamic> route) => false);

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

第2步:

正在刷新屏幕。如果您正在使用Bloc,那么它将非常有帮助。

runApp(MyApp());

在哪里, 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());

这是我的登出方法,

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());
  }

答案 6 :(得分:2)

首先查看 chrislondon 的回答,然后知道如果您无权访问(上下文),您也可以这样做。

[2]

答案 7 :(得分:2)

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

Navigator.pushNamedAndRemoveUntil(" The Route you want to go to " , (Route route) => false);

答案 8 :(得分:0)

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

 Navigator.of(context).pushAndRemoveUntil(MaterialPageRoute(builder: (context) =>
    LoginScreen()), (Route<dynamic> route) => false),

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

答案 9 :(得分:0)

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

Navigator.pushAndRemoveUntil(context,   
                        MaterialPageRoute(builder: (BuildContext context) => Login()),    
                        ModalRoute.withName('/'));   

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

答案 10 :(得分:0)

不确定我是否做对了

但是这适合我直到用root小部件弹出的用例

void popUntilRoot({Object result}) {
    if (Navigator.of(context).canPop()) {
      pop();
      popUntilRoot();
    }
}

答案 11 :(得分:0)

to clear route - 

  onTap: () {
                    //todo to clear route -
                    Navigator.of(context).pop();
                    Navigator.push(context, MaterialPageRoute(builder: (context) => UpdateEmployeeUpdateDateActivity(_token),));
                    widget.listener.onEmployeeDateClick(_day,_month, _year);
}

答案 12 :(得分:-1)

这是个好问题,如果您不知道“pushNamedAndRemoveUntil”!

您想删除导航器堆栈中的每条路线。因此,您的条件必须始终返回 false。可以这样实现:-

Navigator.of(context).pushNamedAndRemoveUntil('/login', (Route<dynamic> route) => false);