Reputation: 125
How to prevent web back button to navigate?
I have try different routing library( go router, auto route, get, on generated route), but those seems not working to stop back button or my practice is not good.
All I want is, supposed there is a login page, after user login, it will route to home page, in this page, user cannot click browser back button to navigate back just like android back button .
When I try to use go router, the go router navigator stack is not sync as browser stack, when I use go to a page (PageA) from PageB, suppose the PageB is remove, but when i click back button, it still can back to PageB. It is weird
I try to use PopScope to prevent navigate back. But some library didn't work( go router, auto route).
I try to use on generated route, it can prevent the navigation, but the path still change, how to prevent it?
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MyHomePage(),
onGenerateRoute: (RouteSettings settings) => AppRoutes.getRoute(
settings,
// observer: observer,
),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage();
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text(
'My Home',
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
Navigator.pushNamed(context, '/one');
// Navigator.push(
// context,
// MaterialPageRoute(
// builder: (context) => One(),
// settings: RouteSettings(name: "one"),
// ),
// );
},
tooltip: 'Increment',
child: const Icon(Icons.add),
),
);
}
}
class One extends StatefulWidget {
@override
State<One> createState() => _OneState();
}
class _OneState extends State<One> {
@override
Widget build(BuildContext context) {
return PopScope(
canPop: false,
onPopInvoked: (didPop) {
if (didPop) {
return;
}
showDialog(
context: context,
builder: (BuildContext context) {
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text('can not pop'),
ElevatedButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text('OK'),
),
],
),
);
});
},
child: Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text(
'One',
),
ElevatedButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text('OK'),
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {},
tooltip: 'Increment',
child: const Icon(Icons.add),
),
),
);
}
}
class AppRoutes {
static const one = "/one";
static const two = "/two";
static const login = "/login";
static const home = "/home";
static MaterialPageRoute getRoute(RouteSettings settings) {
switch (settings.name) {
case AppRoutes.one:
return MainRoute(One(), settings: settings);
default:
return MainRoute(MyHomePage(), settings: settings);
}
}
}
class MainRoute<T> extends MaterialPageRoute<T> {
MainRoute(
Widget widget, {
RouteSettings? settings,
}) : super(builder: (_) => widget, settings: settings);
}
Here is auto route example, it cannot be show the PopScope when I click back button. Repo: https://github.com/nepali-programmer/auto_route_integration/tree/auto_route_setup
Add PopScope in ScreenB, the print('!!!') is printed, but the dialog didn't show up, and the page changed.
@RoutePage()
class ScreenB extends StatelessWidget {
const ScreenB({super.key});
@override
Widget build(BuildContext context) {
return PopScope(
canPop: false,
onPopInvoked: (didPop) {
print('!!!!!!!!!!!!!!!!');
print(didPop);
if (didPop) {
return;
}
showDialog(
context: context,
builder: (BuildContext context) {
return Scaffold(
body: Column(
children: [
Text('can not pop'),
ElevatedButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text('OK'),
),
],
),
);
});
},
child: Scaffold(
appBar: AppBar(),
backgroundColor: Colors.blue,
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
ElevatedButton(
child: const Text('Goto Screen c'),
onPressed: () {
context.router.push(const RouteC());
},
),
],
),
),
);
}
}```
Upvotes: 2
Views: 196
Reputation: 1301
I think you can't actually prevent users from going back to a page. It will confuse them, also if any error occured within the app, it is not possible to go back (obviously). What you can do tho is handle a case by case scenario. In example, if user is loged in, then when he comes back to the login screen, you can check if users is loged in and display a Text saying "You are loged in" or something like that.
Upvotes: 0