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

相关推荐
黄毛火烧雪下2 小时前
(二)Flutter插件之Android插件开发
android·flutter
明月与玄武3 小时前
Melos 使用指南:Flutter / Dart 多包管理工具!
flutter·melos 使用指南·dart 多包管理工具
shr007_13 小时前
flutter 鸿蒙
flutter·华为·harmonyos
Bryce李小白13 小时前
Flutter 与原生混合编程
flutter
wahkim17 小时前
移动端开发工具集锦
flutter·ios·android studio·swift
傅里叶17 小时前
Flutter / Dart 多包管理工具 —— Melos 使用指南
flutter
西西学代码19 小时前
Flutter---生命周期
flutter
LiWeNHuI20 小时前
Flutter开发:发布插件到Pub
flutter
衿璃1 天前
Flutter应用架构设计的思考
前端·flutter
QuantumLeap丶1 天前
《Flutter全栈开发实战指南:从零到高级》- 04 - Widget核心概念与生命周期
flutter·xcode