flutter 拦截返回按钮的方法(WillPopScope or PopScope)

为了避免用户误触返回按钮而导致 App 退出,或者某些页面需要在退出时弹出二次确认弹窗,所以需要拦截返回按钮并进行自行处理。

1.在 flutter 3.12 以下 推荐使用 WillPopScope 组件来实现返回按钮的拦截(该组件在3.12已经被弃用); WillPopScope 的默认构造函数

dart 复制代码
const WillPopScope({
	required WillPopCallback onWillPop,
	required Widget child
})

onWillPop是一个回调函数,当用户点击返回按钮时被调用(包括导航返回按钮及Android的物理返回按钮,还有侧滑返回)。该回调需要返回一个 Future<bool>对象,如果返回的Future最终值为 false 时,则当前路由不出栈(不会返回); 最终值为true时,当前路由出栈退出。当我们使用这个组件的时候 通过这个回调来决定是否退出。

注意 : 如果使用 GetX 路由时在GetX 4.7.2 版本及以上时 WillPopScope 的侧滑返回会失效

WillPopScope 示例

为了防止用户误触返回按钮退出应用,我们拦截返回事件。当用户在1秒内点击两次返回按钮时,则退出;如果间隔超过1秒则不退出,并重新计时。代码如下:

scala 复制代码
import 'package:flutter/material.dart';  
class WillPopScopeTestRoute extends StatefulWidget {  
  WillPopScopeTestRoute({Key? key}) : super(key: key);  
  
  @override  
  State<WillPopScopeTestRoute> createState() => _WillPopScopeTestRouteState();  
}  
  
class _WillPopScopeTestRouteState extends State<WillPopScopeTestRoute>{  
  var lastClickTime = 0;  
  @override  
  Widget build(BuildContext context) {  
    return WillPopScope( onWillPop: ()async{  
      var nowTime = DateTime  
          .now()  
          .millisecondsSinceEpoch;  
      if(nowTime - lastClickTime < 1000 && lastClickTime != 0){  
        return true;  
      }  
      lastClickTime = nowTime;  
      return false;  
    },  
      child: Container(  
        alignment: Alignment.center,  
        child: const Text("1秒内连续按两次返回键退出"),  
      ),  
    );  
  }  
}

2.在 flutter 3.12 及以上 推荐使用 PopScope 组件来实现返回按钮的拦截; PopScope的默认构造函数

dart 复制代码
const PopScope({
  required Widget child,  
  bool canPop = true,  
  PopInvokedWithResultCallback? onPopInvokedWithResult
})

canPop 是一个 bool 值,设置为true 时不拦截,false 时拦截(包括导航返回按钮及Android的物理返回按钮,还有侧滑返回)。 onPopInvokedWithResult 是一个回调函数,在路由弹出后调用该函数。

dart 复制代码
typedef PopInvokedWithResultCallback<T> = void Function(bool didPop, T? result);

该回调函数有两个入参 didPoptrue 时返回键退出未拦截退出成功, 为 false 时返回键拦截未退出。 resultGet.back(result: "11"); 返回的 result 值。

注意 :如果使用 GetX 路由时在GetX 4.7.2 版本以下时 PopScope 的侧滑返回会失效

PopScope 示例

为了防止用户误触返回按钮退出应用,我们拦截返回事件。当用户在1秒内点击两次返回按钮时,则退出;如果间隔超过1秒则不退出,并重新计时。代码如下:

scala 复制代码
import 'package:flutter/material.dart';  
import 'package:get/get.dart';  
class WillPopScopeTestRoute extends StatefulWidget {  
  WillPopScopeTestRoute({Key? key}) : super(key: key);  
  
  @override  
  State<WillPopScopeTestRoute> createState() => _WillPopScopeTestRouteState();  
}  
  
class _WillPopScopeTestRouteState extends State<WillPopScopeTestRoute>{  
  var lastClickTime = 0;  
  @override  
  Widget build(BuildContext context) {  
    return PopScope(  
      canPop: false,  
      onPopInvokedWithResult: (didPop,result) async {  
        if(didPop){  
          //已经返回成功 就不用触发未拦截的逻辑了
          return ;  
        }  
        var nowTime = DateTime  
            .now()  
            .millisecondsSinceEpoch;  
        if (nowTime - lastClickTime < 1000 && lastClickTime != 0) {  
          Get.back();  
        }  
        lastClickTime = nowTime;  
      },  
      child: Container(  
        alignment: Alignment.center,  
        child: const Text("1秒内连续按两次返回键退出"),  
      ),  
    );  
  }  
}

关于 PopScope 在getX 4.7.2 版本以下 失效的原因请看 flutter getx 路由侧滑返回 PopScope 回调失效的探究与解决本文主要探讨了在基于 Getx 项目路由模 - 掘金

相关推荐
小严家1 天前
Flutter完整开发指南 | Flutter&Dart – The Complete Guide
开发语言·flutter
倾云鹤1 天前
flutter实现Function Call
flutter·llm·function call
程序员老刘·2 天前
Flutter版本选择指南:避坑3.27 | 2025年9月
flutter·跨平台开发·客户端开发
懒得不想起名字2 天前
Flutter二维码的生成和扫描
flutter
鹏多多2 天前
flutter-详解控制组件显示的两种方式Offstage与Visibility
前端·flutter
猪哥帅过吴彦祖2 天前
Flutter 系列教程:常用基础组件 (上) - `Text`, `Image`, `Icon`, `Button`
android·flutter·ios
恋猫de小郭2 天前
Fluttercon EU 2025 :Let's go far with Flutter
android·前端·flutter
小李飞刀李寻欢2 天前
flutter 详细解读
flutter
QQ12958455043 天前
错误解决:Flutter找不到合适的Visual Studio 工具链
flutter·visual studio