颤振删除所有路线


107

我想开发一个注销按钮,该按钮会将我发送到登录路线,并从中删除所有其他路线Navigator。该文档似乎并未解释如何制作RoutePredicate或具有任何removeAll函数。

Answers:


277

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

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

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


1
非常感谢,它工作成功。您能否发送一些链接,以便我进一步了解
...。– Pawan

我对此有疑问!在iOS上,通过使用本机视图作为窗口小部件,使用您的方法后,本机视图无法正确处理并继续存在,因此我拥有一个视图,该视图将不再在某种背景下运行并且无法处理。这似乎仅在iOS设备上发生。
洛伦佐(Lorenzo Imperatrice),

@LorenzoImperatrice是否找到解决此问题的方法?我遇到类似的问题
Mateusz Tylman,

3
使用此方法后,我仍然有打开的实例。还有其他解决方案来推动屏幕和删除其余的堆栈吗?
Manoj MM

我们如何使用这种方法传递参数。
Developine

84

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

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

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


27

另一种选择是 popUntil()

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

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


1
我更喜欢这个答案!
noveleven


11

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

例:

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

使用route为HomePage时,您检查小部件的名称。


什么是NoAnimatedRoute?无法在Flutter中找到具有此类名称的课程
kashlo,2010年

@kashlo不要关注=)只是我的实现可以使用MaterialPageRoute代替。但是,我已经编辑了答案,谢谢。
Volodymyr Bilovus

(Route <dynamic>路由)=> route.isFirst)如果有人要删除直到第一个路由。
侯赛因海达尔

7

如果您使用namedRoutes,则可以通过以下简单方法进行操作:

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

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

注意 :

该语句删除堆栈中的所有路由,并使被压入的路由成为根。


4

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

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

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


2

这对我有用。实际上,我正在使用bloc,但是我的问题是登录屏幕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());
  }

0

不知道我是否做对了

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

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

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);
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.