I am struggling in my app:
After the user logs in I navigate to my HomeView
with pushReplaceNamed
, so the user should not be able to pop (by dragging) on the HomeView
because in my thought it is the root view. However that is not the case.. Even after calling pushReplaceNamed
the user can still drag to pop:
I simply call:
Navigator.pushReplacementNamed(
context,
Views.home,
);
On the first start of the App StartView
is displayed, from there I navigate to EmailView
and from there to LoginView
. The code above is inside my LoginView
. In all the other views I simply call pushNamed
.
What am I missing here? Why can the user drag pop on HomeView
?
(I know I can disable it with WillPopScope
, but that does not feel right...)
This is my setup in my MaterialApp
:
Widget build(BuildContext context) {
return MaterialApp(
title: 'AppFlug',
navigatorKey: Get.key,
theme: ThemeData(
fontFamily: AppTextStyles.montserrat,
primarySwatch: ColorService.createMaterialColor(
AppColors.blue,
),
backgroundColor: AppColors.white,
scaffoldBackgroundColor: AppColors.white,
),
initialRoute:
AuthenticationService.isLoggedIn() ? Views.home : Views.start,
onGenerateRoute: AppRouter.generateRoute,
);
}
And here is my AppRouter
:
class AppRouter {
static Route<dynamic> generateRoute(RouteSettings settings) {
switch (settings.name) {
case Views.start:
return MaterialPageRoute(
builder: (context) => const StartView(),
);
case Views.email:
return MaterialPageRoute(
builder: (context) => EmailView(),
);
case Views.signUp:
String email = settings.arguments as String;
return MaterialPageRoute(
builder: (context) => SignUpView(
email: email,
),
);
case Views.login:
String email = settings.arguments as String;
return MaterialPageRoute(
builder: (context) => LoginView(
email: email,
),
);
case Views.home:
return MaterialPageRoute(
builder: (context) => HomeView(),
);
default:
return MaterialPageRoute(
builder: (_) => Scaffold(
body: Center(
child: Text(
'No route defined for ${settings.name}',
),
),
),
);
}
}
}
With the help of Omar I got it working: so pushReplaceNamed
is only replacing the top most route. In my case all I had to do was call:
Navigator.pushNamedAndRemoveUntil(
context,
Views.home,
(route) => false,
);
To quote the doc
:
To remove all the routes below the pushed route, use a [RoutePredicate] that always returns false (e.g. (Route route) => false).