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 项目路由模 - 掘金

相关推荐
_阿南_4 分钟前
不是每一个Widget都会生成一个RenderObject
flutter
世人万千丶8 小时前
鸿蒙Flutter Flex多子组件权重分配
学习·flutter·华为·harmonyos·鸿蒙
GitLqr9 小时前
Flutter 无障碍开发实战:玩转 Semantics 解决视障用户使用痛点
android·flutter·dart
世人万千丶16 小时前
鸿蒙Flutter Flexible与Expanded的区别
学习·flutter·harmonyos·鸿蒙
YM52e16 小时前
鸿蒙Flutter Center居中组件:Align对齐详解
android·学习·flutter·华为·harmonyos·鸿蒙
马里马里奥-19 小时前
LLM-Switch 代理:Flutter 适配与踩坑记录
flutter
浮江雾19 小时前
Flutter第十节-----Flutter布局与组件全解析
android·开发语言·前端·学习·flutter·入门
浮江雾19 小时前
Flutter第12节-----Flutter中Dio插件网络请求全解析
flutter
末代iOS程序员华仔20 小时前
Cursor + GitOps:自动化运维新姿势
flutter·ios·swift
世人万千丶21 小时前
鸿蒙Flutter Flex嵌套布局技巧
学习·flutter·华为·harmonyos·鸿蒙·鸿蒙系统