Ich möchte eine Abmeldeschaltfläche entwickeln, die mich zur Anmelderoute sendet und alle anderen Routen aus der entfernt Navigator
. Die Dokumentation scheint nicht zu erklären, wie man eine RoutePredicate
Funktion removeAll erstellt oder hat.
98
Ich kann mit dem folgenden Code-Snippet fertig sein:
Navigator.of(context).pushAndRemoveUntil(MaterialPageRoute(builder: (context) => LoginScreen()), (Route<dynamic> route) => false),
Wenn Sie die gesamte Route unterhalb der Push- Route entfernen möchten, gibt RoutePredicate immer false zurück , z. B. (Route route) => false .
quelle
Eine andere Alternative ist
popUntil()
Navigator.of(context).popUntil(ModalRoute.withName('/root'));
Dadurch werden alle Routen entfernt, bis Sie wieder an der angegebenen Route sind.
quelle
Eine andere Lösung ist zu verwenden
pushAndRemoveUnit()
. Um alle anderen Routen zu entfernen, verwenden SieModalRoute.withName('/')
Navigator.pushAndRemoveUntil(context, MaterialPageRoute(builder: (BuildContext context) => Login()), ModalRoute.withName('/'));
Referenz: https://api.flutter.dev/flutter/widgets/NavigatorState/pushAndRemoveUntil.html
quelle
Wenn Sie zum jeweiligen Bildschirm zurückkehren möchten und keinen benannten Router verwenden, können Sie den nächsten Ansatz verwenden
Beispiel:
Navigator.pushAndRemoveUntil(context, MaterialPageRoute(builder: (BuildContext context) => SingleShowPage()), (Route<dynamic> route) => route is HomePage );
Mit route is HomePage überprüfen Sie den Namen Ihres Widgets.
quelle
Wenn Sie namedRoutes verwenden, können Sie dies einfach tun:
Navigator.pushNamedAndRemoveUntil(context, "/login", (Route<dynamic> route) => false);
Wobei "/ login" die Route ist, die Sie auf den Routenstapel verschieben möchten.
Beachten Sie, dass :
quelle
Ich weiß nicht, warum niemand die Lösung mit SchedularBindingInstance erwähnt hat. Ein bisschen zu spät zur Party. Ich denke, dies wäre der richtige Weg, dies zu tun. Ursprünglich hier beantwortet
SchedulerBinding.instance.addPostFrameCallback((_) async { Navigator.of(context).pushNamedAndRemoveUntil( '/login', (Route<dynamic> route) => false); });
Der obige Code entfernt alle Routen und Naviagtes zu '/ login'. Dies stellt auch sicher, dass alle Frames gerendert werden, bevor Sie durch Planen eines Rückrufs zu einer neuen Route navigieren
quelle
Das funktioniert bei mir. Eigentlich habe ich mit Block gearbeitet, aber mein Problem war der Block des Anmeldebildschirms. Es wurde nach dem Abmelden nicht aktualisiert. Es enthielt die vorherigen Modelldaten. Sogar ich habe den falschen Eintrag eingegeben. Es ging zum Startbildschirm.
Schritt 1:
Navigator.of(context).pushNamedAndRemoveUntil( UIData.initialRoute, (Route<dynamic> route) => false);
wo,
UIData.initialRoute = "/" or "/login"
Schritt 2:
Es funktioniert, um den Bildschirm zu aktualisieren. Wenn Sie mit Bloc arbeiten, ist dies sehr hilfreich.
wo,
MyApp() is the root class.
Code der Stammklasse (dh 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());
Hier ist meine Abmeldemethode :
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()); }
quelle
Ich bin mir nicht sicher, ob ich das richtig mache
Dies passt jedoch zu meinem Anwendungsfall, bis zum Root-Widget zu poppen
void popUntilRoot({Object result}) { if (Navigator.of(context).canPop()) { pop(); popUntilRoot(); } }
quelle
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); }
quelle