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.
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.
Antworten:
Dies konnte ich mit folgendem Code erreichen:
Navigator.of(context)
.pushNamedAndRemoveUntil('/login', (Route<dynamic> route) => false);
Das Geheimnis hier ist die Verwendung eines RoutePredicate, das immer false zurückgibt (Route<dynamic> route) => false
. In dieser Situation werden alle Routen mit Ausnahme der neuen /login
Route entfernt, die ich gedrückt habe.
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 .
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
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.
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 :
Diese Anweisung entfernt alle Routen im Stapel und macht die Push-Route zur Wurzel.
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
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.
runApp(MyApp());
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());
}
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();
}
}