Flutter - How catch back button(hardware) event?

Flutter - How catch back button(hardware) event?

In Flutter, you can catch and handle the hardware back button event on Android using the WillPopScope widget. This widget provides a way to intercept the back button press and perform custom actions before the default behavior occurs.

Here's a step-by-step guide on how to use WillPopScope to catch and handle the back button event:

Using WillPopScope Widget

  1. Wrap Your Widget with WillPopScope:

    • The WillPopScope widget intercepts the back button press event. Wrap the widget tree where you want to handle the back button event with WillPopScope.
  2. Provide a Callback Function:

    • Implement the callback function that will be triggered when the back button is pressed. This function should return a Future<bool>. If it returns true, the default back button behavior occurs; if it returns false, the back button action is prevented.

Example: Handling Back Button Press

import 'package:flutter/material.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: MyHomePage(), ); } } class MyHomePage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Back Button Handling Example'), ), body: WillPopScope( onWillPop: () async { // Custom logic before the back button is handled bool shouldPop = await _showExitConfirmationDialog(context); return shouldPop; // If true, the back button action proceeds, otherwise it is canceled. }, child: Center( child: Text('Press the back button to see the effect.'), ), ), ); } Future<bool> _showExitConfirmationDialog(BuildContext context) async { return showDialog<bool>( context: context, barrierDismissible: false, builder: (BuildContext context) { return AlertDialog( title: Text('Exit Confirmation'), content: Text('Do you really want to exit?'), actions: <Widget>[ TextButton( onPressed: () { Navigator.of(context).pop(true); // Return true to allow back navigation }, child: Text('Yes'), ), TextButton( onPressed: () { Navigator.of(context).pop(false); // Return false to prevent back navigation }, child: Text('No'), ), ], ); }, ) ?? false; } } 

Explanation:

  1. Wrap with WillPopScope:

    • WillPopScope is used to wrap the Scaffold or any widget where you want to handle the back button event.
  2. Implement onWillPop:

    • The onWillPop callback is triggered when the back button is pressed. In this example, _showExitConfirmationDialog is a method that shows a confirmation dialog.
  3. Return Value:

    • The callback function should return a Future<bool>. Returning true will let the back button proceed with its default behavior, while returning false will cancel the action.
  4. Custom Logic:

    • You can implement any custom logic within the onWillPop callback, such as showing a dialog or performing other actions.

Handling Back Button in a StatefulWidget

If you need to manage the back button press state within a StatefulWidget, you can handle it similarly but within the state class:

import 'package:flutter/material.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: MyHomePage(), ); } } class MyHomePage extends StatefulWidget { @override _MyHomePageState createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Back Button Handling Example'), ), body: WillPopScope( onWillPop: _handleBackButton, child: Center( child: Text('Press the back button to see the effect.'), ), ), ); } Future<bool> _handleBackButton() async { bool shouldPop = await _showExitConfirmationDialog(context); return shouldPop; } Future<bool> _showExitConfirmationDialog(BuildContext context) async { return showDialog<bool>( context: context, barrierDismissible: false, builder: (BuildContext context) { return AlertDialog( title: Text('Exit Confirmation'), content: Text('Do you really want to exit?'), actions: <Widget>[ TextButton( onPressed: () { Navigator.of(context).pop(true); }, child: Text('Yes'), ), TextButton( onPressed: () { Navigator.of(context).pop(false); }, child: Text('No'), ), ], ); }, ) ?? false; } } 

This approach provides a way to handle the back button event in Flutter and perform custom actions based on user input or other conditions.

Examples

  1. "Flutter catch hardware back button event in a StatefulWidget"

    • Description: Handle the hardware back button event within a StatefulWidget using WillPopScope.
    • Code:
      import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: MyHomePage(), ); } } class MyHomePage extends StatefulWidget { @override _MyHomePageState createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { Future<bool> _onWillPop() async { // Handle the back button event here print('Back button pressed'); return true; // Return true to allow default behavior } @override Widget build(BuildContext context) { return WillPopScope( onWillPop: _onWillPop, child: Scaffold( appBar: AppBar(title: Text('Back Button Handling')), body: Center(child: Text('Press the back button')), ), ); } } 
  2. "Flutter intercept hardware back button press in a screen"

    • Description: Use WillPopScope to intercept and handle the back button press on a specific screen.
    • Code:
      import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: FirstScreen(), ); } } class FirstScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('First Screen')), body: Center( child: ElevatedButton( child: Text('Go to Second Screen'), onPressed: () { Navigator.push( context, MaterialPageRoute(builder: (context) => SecondScreen()), ); }, ), ), ); } } class SecondScreen extends StatelessWidget { @override Widget build(BuildContext context) { return WillPopScope( onWillPop: () async { print('Back button pressed on Second Screen'); return true; }, child: Scaffold( appBar: AppBar(title: Text('Second Screen')), body: Center(child: Text('Press the back button')), ), ); } } 
  3. "Flutter back button event with confirmation dialog"

    • Description: Show a confirmation dialog when the hardware back button is pressed.
    • Code:
      import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: ConfirmBackButtonScreen(), ); } } class ConfirmBackButtonScreen extends StatefulWidget { @override _ConfirmBackButtonScreenState createState() => _ConfirmBackButtonScreenState(); } class _ConfirmBackButtonScreenState extends State<ConfirmBackButtonScreen> { Future<bool> _onWillPop() async { final shouldPop = await showDialog( context: context, builder: (context) => AlertDialog( title: Text('Confirm'), content: Text('Do you really want to exit?'), actions: [ TextButton( child: Text('Cancel'), onPressed: () => Navigator.of(context).pop(false), ), TextButton( child: Text('OK'), onPressed: () => Navigator.of(context).pop(true), ), ], ), ); return shouldPop ?? false; } @override Widget build(BuildContext context) { return WillPopScope( onWillPop: _onWillPop, child: Scaffold( appBar: AppBar(title: Text('Back Button Confirmation')), body: Center(child: Text('Press the back button')), ), ); } } 
  4. "Flutter handle back button press in a modal dialog"

    • Description: Handle the back button event when a modal dialog is open.
    • Code:
      import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: MyHomePage(), ); } } class MyHomePage extends StatelessWidget { void _showDialog(BuildContext context) { showDialog( context: context, barrierDismissible: false, builder: (context) { return AlertDialog( title: Text('Modal Dialog'), content: Text('Pressing back button will close this dialog.'), actions: [ TextButton( child: Text('OK'), onPressed: () => Navigator.of(context).pop(), ), ], ); }, ); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('Dialog Handling')), body: Center( child: ElevatedButton( child: Text('Show Dialog'), onPressed: () => _showDialog(context), ), ), ); } } 
  5. "Flutter disable hardware back button on a specific screen"

    • Description: Disable the hardware back button on a specific screen.
    • Code:
      import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: DisableBackButtonScreen(), ); } } class DisableBackButtonScreen extends StatelessWidget { Future<bool> _onWillPop() async { // Prevent back button from doing anything return false; } @override Widget build(BuildContext context) { return WillPopScope( onWillPop: _onWillPop, child: Scaffold( appBar: AppBar(title: Text('Back Button Disabled')), body: Center(child: Text('Back button is disabled on this screen')), ), ); } } 
  6. "Flutter back button handling with nested navigation"

    • Description: Handle the back button in a nested navigation scenario.
    • Code:
      import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: HomeScreen(), ); } } class HomeScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('Home Screen')), body: Center( child: ElevatedButton( child: Text('Go to Nested Screen'), onPressed: () { Navigator.push( context, MaterialPageRoute(builder: (context) => NestedScreen()), ); }, ), ), ); } } class NestedScreen extends StatelessWidget { @override Widget build(BuildContext context) { return WillPopScope( onWillPop: () async { // Handle back navigation print('Back button pressed on Nested Screen'); return true; }, child: Scaffold( appBar: AppBar(title: Text('Nested Screen')), body: Center(child: Text('Press the back button')), ), ); } } 
  7. "Flutter detect back button press and navigate programmatically"

    • Description: Detect the back button press and navigate to a different screen programmatically.
    • Code:
      import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: FirstScreen(), ); } } class FirstScreen extends StatelessWidget { @override Widget build(BuildContext context) { return WillPopScope( onWillPop: () async { Navigator.pushReplacement( context, MaterialPageRoute(builder: (context) => SecondScreen()), ); return false; // Prevent default back action }, child: Scaffold( appBar: AppBar(title: Text('First Screen')), body: Center(child: Text('Press the back button')), ), ); } } class SecondScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('Second Screen')), body: Center(child: Text('You are now on the second screen')), ); } } 
  8. "Flutter handle hardware back button press in a BottomSheet"

    • Description: Handle the back button event when a BottomSheet is open.
    • Code:
      import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: HomeScreen(), ); } } class HomeScreen extends StatelessWidget { void _showBottomSheet(BuildContext context) { showModalBottomSheet( context: context, builder: (context) { return WillPopScope( onWillPop: () async { print('BottomSheet back button pressed'); return true; // Allow closing the BottomSheet }, child: Container( height: 200, child: Center(child: Text('Bottom Sheet')), ), ); }, ); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('Bottom Sheet Handling')), body: Center( child: ElevatedButton( child: Text('Show Bottom Sheet'), onPressed: () => _showBottomSheet(context), ), ), ); } } 
  9. "Flutter handle hardware back button and avoid navigation stack clearing"

    • Description: Handle the back button press to avoid clearing the navigation stack.
    • Code:
      import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: HomeScreen(), ); } } class HomeScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('Home Screen')), body: Center( child: ElevatedButton( child: Text('Go to Next Screen'), onPressed: () { Navigator.push( context, MaterialPageRoute(builder: (context) => NextScreen()), ); }, ), ), ); } } class NextScreen extends StatelessWidget { @override Widget build(BuildContext context) { return WillPopScope( onWillPop: () async { Navigator.pop(context); // Pop the current screen return false; // Prevent the default back action }, child: Scaffold( appBar: AppBar(title: Text('Next Screen')), body: Center(child: Text('Press the back button')), ), ); } } 
  10. "Flutter handle hardware back button for custom back navigation"

    • Description: Customize the back navigation behavior in Flutter.
    • Code:
      import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: CustomBackNavigationScreen(), ); } } class CustomBackNavigationScreen extends StatefulWidget { @override _CustomBackNavigationScreenState createState() => _CustomBackNavigationScreenState(); } class _CustomBackNavigationScreenState extends State<CustomBackNavigationScreen> { Future<bool> _onWillPop() async { // Custom back navigation logic print('Custom back navigation'); Navigator.push( context, MaterialPageRoute(builder: (context) => DifferentScreen()), ); return false; // Prevent default back action } @override Widget build(BuildContext context) { return WillPopScope( onWillPop: _onWillPop, child: Scaffold( appBar: AppBar(title: Text('Custom Back Navigation')), body: Center(child: Text('Press the back button')), ), ); } } class DifferentScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('Different Screen')), body: Center(child: Text('You navigated to a different screen')), ); } } 

More Tags

nsstring pycurl shadow r-car reactive package java-ee-6 file-exists user-experience android-source

More Programming Questions

More Pregnancy Calculators

More Bio laboratory Calculators

More Geometry Calculators

More Tax and Salary Calculators