颤振移除所有路线

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

178824 次浏览

我用下面的代码完成了这一点:

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

这里的秘诀是使用一个RoutePredicate,它总是返回false__abc0。在这种情况下,它会删除除我推送的新/login路由之外的所有路由。

另一种选择是popUntil()

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

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

我可以完成以下代码片段:

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

如果要删除推送的路由下面的所有路由,路由谓词总是返回错误,例如(路线路线)=>;错误

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

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

参考:https://api.flutter.dev/flutter/widgets/navigatorstate/pushandremoveuntil.html

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

示例:

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

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

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

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

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

这对我有用。实际上,我使用的是布洛克,但我的问题是登录屏幕阻塞。注销后未更新。它保存了以前的模型数据。甚至,我输入了错误的条目,它将进入主屏幕。

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

如果您使用的是NamedRoutes,则只需执行以下操作即可:

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

其中,";/登录";是要压入路由堆栈的路由。

请注意:

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

不确定我这样做是否正确。

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

void popUntilRoot({Object result}) {
if (Navigator.of(context).canPop()) {
pop();
popUntilRoot();
}
}
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);
}

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

navigatorKey.currentState.pushNamedAndRemoveUntil('/login', (Route<dynamic> route) => false);

在我的例子中,这个解决方案是可行的:

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

在我的情况下,我有这幅画 第1页(主要)->;第2页->;第3页->;第四页.

当我必须转到第4页时,返回的第2页和第3页不必出现,但我必须再次转到第1页在这一点上转到第4页,我做了:

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

说明如下:转到第4页(健身程序),并删除所有以前的页面,直到第1页,即(主要)。

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

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

也就是说,去登录并删除所有以前的页面,因为有一个假的。

使用popuntil,如下所示

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

使用这个,它为我完美地工作:

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

确保添加了最后一行,即参数,然后就可以开始了。