Reputation: 568
I created two pages one is login and main page but i want close app from main page i am using Willpopscope
but it is not working for me i have tried all things but the onwillpop
method is not calling please help me thank you.
class main_page extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(primarySwatch: Colors.amber),
home: my_page(),
);
}
}
class my_page extends StatefulWidget {
@override
_my_pageState createState() => _my_pageState();
}
class _my_pageState extends State<my_page> {
@override
void initState() {
check_login();
super.initState();
}
Future check_login() async {
SharedPreferences preferences = await SharedPreferences.getInstance();
if (preferences.getBool("islogin") == false)
setState(() {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => MyApp(),
));
});
}
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () async=>false,
child: Scaffold(
appBar: new AppBar(
title: Text(
"Home",
style: new TextStyle(color: Colors.white),
),
actions: <Widget>[
FlatButton(
onPressed: () async {
SharedPreferences sharedPreferences =
await SharedPreferences.getInstance();
setState(() {
sharedPreferences.setBool("islogin", false);
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => main_page(),
));
});
},
child: Text(
"Logout",
style: TextStyle(color: Colors.white, fontSize: 16.0),
))
],
),
),
);
}
}
I am also using Shredprefrences
but i think it does not matter i want close app from my main_page please help me for this Thank you.
Upvotes: 10
Views: 29692
Reputation: 356
I was struggling with this problem, none of answers helped but finally I found the correct answer in BackButton
widget source code.
When we use WillPopScope
on top of our widget, we should use maybePop
instead of pop
method that forces the Navigator
to pop the last pushed page in order to let the WillPopScope
widget decides the next action.
Navigator.maybePop(context);
Upvotes: 16
Reputation: 1009
I resolved this error as in my case I have a parent screen and in that, I have PageView. I was trying to call WillPopScope in one of my PageView and then I realized my parent have WillPopScope too.
That is why it is not calling WillPopScope of PageView
Upvotes: 0
Reputation: 1
don't use on Scaffold(), wrap your MaterialApp as in the example
bool allowed = false;
return WillPopScope(
onWillPop: () async {
print('MJD POP TRYING TO GET BACK from login Page');
return Future.value(allowed);
},
child: MaterialApp(
title: 'Your App Title',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyLoginPage(title: 'Login Page'),
),
);
Upvotes: -5
Reputation: 3767
Just check out this answer and let me know if it works:
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:flutter/services.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(primarySwatch: Colors.amber),
home: SecondPage(),
);
}
}
class LoginPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: Center(
child: RaisedButton(
child: Text('Move to second page after Login'),
onPressed: () async {
SharedPreferences preferences =
await SharedPreferences.getInstance();
preferences.setBool("islogin", true);
// this will remove the login page after routing to the second page and then the stack will have only one page that is second page.
// so later you can use the willpopscape
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(builder: (context) => SecondPage()),
ModalRoute.withName("/Home"));
},
)),
),
);
}
}
class SecondPage extends StatefulWidget {
@override
_SecondPageState createState() => _SecondPageState();
}
class _SecondPageState extends State<SecondPage> {
@override
void initState() {
check_login();
super.initState();
}
Future check_login() async {
SharedPreferences preferences = await SharedPreferences.getInstance();
if (preferences.getBool("islogin") == null)
//This above if statement will check if the parameter islogin is null then redirect to the login screeen
// else if the value is not null then i will not enter the if statement
setState(() {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => LoginPage(),
));
});
}
Future<bool> _onWillPop() async {
// This dialog will exit your app on saying yes
return (await showDialog(
context: context,
builder: (context) => new AlertDialog(
title: new Text('Are you sure?'),
content: new Text('Do you want to exit an App'),
actions: <Widget>[
new FlatButton(
onPressed: () => Navigator.of(context).pop(false),
child: new Text('No'),
),
new FlatButton(
onPressed: () => Navigator.of(context).pop(true),
child: new Text('Yes'),
),
],
),
)) ??
false;
}
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: _onWillPop,
child: Scaffold(
appBar: new AppBar(
title: Text(
"Home",
style: new TextStyle(color: Colors.white),
),
actions: <Widget>[
FlatButton(
onPressed: () async {
SystemNavigator.pop();
},
child: Text(
"Logout",
style: TextStyle(color: Colors.white, fontSize: 16.0),
))
],
),
),
);
}
}
Upvotes: 5
Reputation: 568
Here is answer example_page
code
class exmp extends StatefulWidget {
@override
_exmpState createState() => _exmpState();
}
class _exmpState extends State<exmp> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("example"),
),
body: Column(
children: <Widget>[
Center(
child: RaisedButton(onPressed: () {
Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(
builder: (context) => my_example(),
),
(route) => false);
}),
)
],
),
);
}
}
And this is my second page my_example
class my_example extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(primarySwatch: Colors.amber),
home: my_examp(),
);
}
}
class my_examp extends StatefulWidget {
@override
_my_exampState createState() => _my_exampState();
}
class _my_exampState extends State<my_examp> {
Future<bool> onbackpress() async{
return true;
}
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: onbackpress,
child: Scaffold(
appBar: AppBar(
title: Text("my_eaxmple"),
),
),
);
}
}
The problem was i am pushing another page from my main page but i forget to remove first page for that i used the Navigator.of(context).pushAndRemoveUntil( MaterialPageRoute(builder: (context) => my_example()(route) => false);
to remove the main page before navigate to another page
Upvotes: 3
Reputation: 2234
This is how you should use
Future<bool> _willPopCallback() async {
// await Show dialog of exit or what you want
// then
return true; //
}
//then use in the build like
WillPopScope(child: new Scaffold(), onWillPop: _willPopCallback)
Upvotes: 0