Reputation: 1341
'WillPopScope' is deprecated and shouldn't be used. Use PopScope instead. This feature was deprecated after v3.12.0-1.0.pre
WillPopScope(
onWillPop: () async {
// your logic
return false;
},
)
Upvotes: 48
Views: 70993
Reputation: 215
it's working
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: AppColors.page_bg_color,
body: PopScope(
canPop: false,
onPopInvokedWithResult: (didPop, result) {
if(didPop) {
return;
}
callBackFunction(context);
},
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
//widget
],
),
),
);
}
void callBackFunction(BuildContext context) {
// handle back button functionality here,
}
Upvotes: 0
Reputation: 835
You can use it like this.
PopScope(
canPop: false,
onPopInvoked: (didPop) async {
if (didPop) {
return;
}
final navigator = Navigator.of(context);
bool value = await someFunction();
if (value) {
navigator.pop();
}
},
)
Edit
onPopInvoked is Deprecated now, use onPopInvokedWithResult instead.
PopScope(
canPop: false,
onPopInvokedWithResult: (didPop, result) async {
if (didPop) {
return;
}
final navigator = Navigator.of(context);
bool value = await someFunction();
if (value) {
navigator.pop(result);
}
},
)
If you call
Navigator.maybePop(context, someData)
you will get someData
in result
Upvotes: 53
Reputation: 581
onPopInvoked Deprecated in Favor of onPopInvokedWithResult
// Old implementation with PopScope
PopScope(
canPop: false,
onPopInvoked : (didPop){
// logic
},
)
// New implementation with PopScope
PopScope(
canPop: false,
onPopInvokedWithResult: (context, result) {
// Handle back navigation
},
child: MyWidget(),
);
Upvotes: 2
Reputation: 59
As of the latest Flutter updates, the WillPopScope
widget has been deprecated and replaced by PopScope
. If you’re maintaining legacy code or starting a new project, it's important to update your code to use PopScope
instead.
// Old implementation with WillPopScope
WillPopScope(
onWillPop: () async {
// Handle back navigation
return true;
},
child: MyWidget(),
);
// New implementation with PopScope
PopScope(
onPopInvokedWithResult: (context, result) {
// Handle back navigation
},
child: MyWidget(),
);
Similarly, the onPopInvoked
callback has been deprecated in favor of onPopInvokedWithResult
. This new callback provides the context
and the result
of the pop event, giving you more flexibility in handling back navigation.
Updating your code to reflect these changes will ensure compatibility with future Flutter releases and take advantage of the latest improvements in navigation handling.
Upvotes: 5
Reputation: 63
This documentation mentions how to migrate from WillPopScope to PopScope:
Migrating from WillPopScope to PopScope
Before Migration:
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () async {
// your logic
return false;
},
child: Scaffold(...),
);
}
After Migration:
@override
Widget build(BuildContext context) {
return PopScope(
canPop: customLogic(),
child: Scaffold(...),
);
}
bool customLogic() {
{
// your logic
return false;
}
}
Upvotes: 6
Reputation: 1
you can use PopScope instead of using willPopScope, Here is my code with the example
first you have to the create a future class to design your alert dialog, in my case, the code is
Future<bool> _showExitConfirmationDialog(BuildContext context) async {
return (await showDialog(
context: context,
builder: (context) => AlertDialog(
backgroundColor: dropDownColor,
elevation: 10,
shadowColor: primaryGradient,
title: MyText(
color: screenText,
text: 'exit',
multilanguage: true,
fontsizeNormal: 20,
fontweight: FontWeight.w900,
),
content: MyText(
color: screenText,
text: 'sure',
multilanguage: true,
fontsizeNormal: 16,
fontweight: FontWeight.bold,
),
actions: <Widget>[
ElevatedButton(
child: MyText(
color: txtdecoColor,
text: 'no',
multilanguage: true,
),
onPressed: () => Navigator.of(context).pop(false),
),
ElevatedButton(
child: MyText(
color: txtdecoColor,
text: 'yes',
multilanguage: true,
),
onPressed: () => SystemNavigator.pop(),
),
],
),
)) ??
false;
}
I have used custom text widget named MyText, you can use the simple Text widget.
After creating the future class, you have to wrap your scaffold with the PopScope widget, and pass the canPop and onPopInvoked.
as per my code, it goes like this:
@override
Widget build(BuildContext context) {
return PopScope(
canPop: false,
onPopInvoked: (bool didPop) async {
if (didPop) {
return;
}
final bool shouldPop = await _showExitConfirmationDialog(context);
if (context.mounted && shouldPop) {
Navigator.pop(context);
}
},
child: Scaffold( //Your body code),);//ending PopScope}
Upvotes: 0
Reputation: 152
Previously my flutter code block:
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () async {
await _stop(); // Stop the speech when the back button is pressed
return true;
},
child: Scaffold (...),
);
}
The updated flutter code block now:
which is working fine without any warning and errors.
Upvotes: 0
Reputation: 1
If you're dealing with PopScope
and flutter_inappwebview
, here's a solution to help you out.
PopScope(
canPop: false,
onPopInvoked: (didPop) async {
await webviewController.goBack();
},
child: ...
)
Upvotes: 0
Reputation: 56
Flutter's recent updates have deprecated the 'WillPopScope' widget in favor of 'PopScope.' This means that the 'WillPopScope' widget, previously used for handling back button presses, is no longer supported and should be replaced with 'PopScope.' Make sure to update your code accordingly to ensure compatibility with the latest versions of Flutter.
PopScope(
onPop: () async {
// your logic
return false;
},
)
Upvotes: 0
Reputation: 1
Future<bool> _onback(BuildContext context) async {
bool? exitApp = await showDialog(
context: context,
builder: ((context) {
return AlertDialog(
title: const Text('¿Quieres salir?',
style: TextStyle(
fontSize: 15,
)),
actions: [
TextButton(
onPressed: () {
Navigator.of(context).pop(false);
},
child: const Text('No')),
TextButton(
onPressed: () {
_flutterRadioPlayer.pause();
_flutterRadioPlayer.stop();
//exit(0);
Navigator.of(context).pop(true);
},
child: const Text('Si'))
],
);
}),
);
return exitApp ?? false;
}
PopScope(
canPop: false,
onPopInvoked: (didPop) async {
debugPrint("didPop1: $didPop");
if (didPop) {
return;
}
final bool shouldPop = await _onback(context);
if (shouldPop) {
SystemNavigator.pop();
}
},
child:
Upvotes: 0
Reputation: 1341
Solved
replace old widget from WillPopScope
to PopScope
new widget check below code
/// NEW CODE
PopScope(
canPop: false,
onPopInvoked : (didPop){
// logic
},
)
Upvotes: 65
Reputation: 48
You can try something like this:
PopScope(
canPop: canPop,
onPopInvoked: (bool value) {
setState(() {
canPop= !value;
});
if (canPop) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text("Click once more to go back"),
duration: Duration(milliseconds: 1500),
),
);
}
},
child:child)
Upvotes: 2
Reputation: 3
This is my current working solution: You can wrap it around your screen in the router and it redirects to your home screen or it shows the snackbar with then closing the app after another press on the go back button.
class GoBackOrCloseOnConfirmationState
extends State<GoBackOrCloseOnConfirmation> {
DateTime? currentBackPressTime;
bool allowPop = false;
bool closeOnConfirm() {
DateTime now = DateTime.now();
if (currentBackPressTime == null ||
now.difference(currentBackPressTime!) > const Duration(seconds: 4)) {
currentBackPressTime = now;
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
behavior: SnackBarBehavior.floating,
content: Center(child: Text('Drücke erneut um die App zu schließen')),
duration: Duration(seconds: 4),
),
);
return false;
}
currentBackPressTime = null;
return true;
}
@override
Widget build(BuildContext context) {
return PopScope(
canPop: false,
onPopInvoked: (bool didPop) => {
widget.closeAppOnConfirmation
? closeOnConfirm()
? SystemNavigator.pop()
: null
: context.go('/')
},
child: widget.child,
);
}
}
Upvotes: 0
Reputation: 10228
PopScope(
canPop: false, //It should be false to work
onPopInvoked : (didPop) {
if (didPop) {
return;
}
Get.back(); //Here this temporary, you can change this line
},
)
Upvotes: 8
Reputation: 1221
Here is a solution with example
import 'package:flutter/material.dart';
void main() => runApp(const NavigatorPopHandlerApp());
class NavigatorPopHandlerApp extends StatelessWidget {
const NavigatorPopHandlerApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
initialRoute: '/home',
routes: <String, WidgetBuilder>{
'/home': (BuildContext context) => const _HomePage(),
'/two': (BuildContext context) => const _PageTwo(),
},
);
}
}
class _HomePage extends StatefulWidget {
const _HomePage();
@override
State<_HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<_HomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text('Page One'),
TextButton(
onPressed: () {
Navigator.of(context).pushNamed('/two');
},
child: const Text('Next page'),
),
],
),
),
);
}
}
class _PageTwo extends StatefulWidget {
const _PageTwo();
@override
State<_PageTwo> createState() => _PageTwoState();
}
class _PageTwoState extends State<_PageTwo> {
void _showBackDialog() {
showDialog<void>(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Are you sure?'),
content: const Text(
'Are you sure you want to leave this page?',
),
actions: <Widget>[
TextButton(
style: TextButton.styleFrom(
textStyle: Theme.of(context).textTheme.labelLarge,
),
child: const Text('Nevermind'),
onPressed: () {
Navigator.pop(context);
},
),
TextButton(
style: TextButton.styleFrom(
textStyle: Theme.of(context).textTheme.labelLarge,
),
child: const Text('Leave'),
onPressed: () {
Navigator.pop(context);
Navigator.pop(context);
},
),
],
);
},
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text('Page Two'),
PopScope(
canPop: false,
onPopInvoked: (bool didPop) {
if (didPop) {
return;
}
_showBackDialog();
},
child: TextButton(
onPressed: () {
_showBackDialog();
},
child: const Text('Go back'),
),
),
],
),
),
);
}
}
Upvotes: 0