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