'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;
},
)
'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;
},
)
Solved
replace old widget from WillPopScope
to PopScope
new widget check below code
/// NEW CODE
PopScope(
canPop: false,
onPopInvoked : (didPop){
// logic
},
)
canPop
to false and handle the pop manually by using onPopInvoked
and use Navigator.pop(context)
–
Tamarah 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();
}
},
didPop
only return true when the route successfully popped. while we set canPop
to false, there's no chance didPop
will be true if you want to prevent the pop, you can set canPop
to false and handle the pop manually by using onPopInvoked
–
Tamarah PopScope(
canPop: false, //It should be false to work
onPopInvoked : (didPop) {
if (didPop) {
return;
}
Get.back(); //Here this temporary, you can change this line
},
)
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)
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;
}
}
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'),
),
),
],
),
),
);
}
}
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,
);
}
}
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:
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: ...
)
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;
},
)
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.
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}
© 2022 - 2024 — McMap. All rights reserved.