我想开发一个注销按钮,该按钮会将我发送到登录路线,并从中删除所有其他路线Navigator
。该文档似乎并未解释如何制作RoutePredicate
或具有任何removeAll函数。
Answers:
我可以使用以下代码完成此任务:
Navigator.of(context)
.pushNamedAndRemoveUntil('/login', (Route<dynamic> route) => false);
这里的秘密是使用总是返回false的RoutePredicate (Route<dynamic> route) => false
。在这种情况下,它将删除除/login
我推送的新路线以外的所有路线。
另一个解决方案是使用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
);
使用route为HomePage时,您检查小部件的名称。
如果您使用namedRoutes,则可以通过以下简单方法进行操作:
Navigator.pushNamedAndRemoveUntil(context, "/login", (Route<dynamic> route) => false);
其中“ / login”是要在路由堆栈上推送的路由。
注意 :
该语句删除堆栈中的所有路由,并使被压入的路由成为根。
我不知道为什么没有人提到使用SchedularBindingInstance的解决方案,但是晚了一点,我认为这是正确的解决方法,最初在这里回答
SchedulerBinding.instance.addPostFrameCallback((_) async {
Navigator.of(context).pushNamedAndRemoveUntil(
'/login',
(Route<dynamic> route) => false);
});
上面的代码删除了所有路由和导航,以使其“ / login”通过调度回调确保在导航到新路由之前渲染所有帧
这对我有用。实际上,我正在使用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());
}
不知道我是否做对了
但这适合我的用例直到通过root小部件弹出
void popUntilRoot({Object result}) {
if (Navigator.of(context).canPop()) {
pop();
popUntilRoot();
}
}