Flutter中PopScope点击安卓返回键出现黑屏问题求助
解决PopScope在进度弹窗中导致黑屏的问题
在Flutter 3.16.3、Dart 3.2.3、DevTools 2.28.4环境下,点击"Press Me"按钮唤起进度弹窗后,在异步任务完成前尝试返回,使用PopScope会触发黑屏,而WillPopScope运行正常。需要用PopScope实现和WillPopScope一致的防返回效果。
问题原因
PopScope的onPopInvoked回调逻辑处理不当,未正确拦截路由弹出行为,导致路由栈状态异常引发黑屏。
修复方案
修改progressDialogue函数中PopScope的使用方式,调整回调逻辑:
progressDialogue(BuildContext context) { // 设置弹窗 AlertDialog alert = const AlertDialog( backgroundColor: Colors.transparent, elevation: 0, content: Center( child: CircularProgressIndicator(), ), ); showDialog( // 阻止点击外部关闭弹窗 barrierDismissible: false, context: context, builder: (BuildContext context) { // 用PopScope拦截返回操作 return PopScope( onPopInvoked: (didPop) async { // 返回true告知框架已处理弹出请求,阻止默认路由弹出 return true; }, child: alert, ); }, ); }
完整代码示例
import 'dart:async'; import 'package:flutter/material.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), useMaterial3: true, ), home: const MyHomePage(), ); } } class MyHomePage extends StatelessWidget { const MyHomePage({super.key}); @override Widget build(BuildContext context) { return Scaffold( body: Center( child: ElevatedButton( onPressed: () async { progressDialogue(context); final futureResults = await simulateFuture(); debugPrint(futureResults); Navigator.pop(context); }, child: const Text('Press Me'), ), ), ); } } Future<String> simulateFuture() { Completer<String> completer = Completer<String>(); // 模拟5秒异步任务 Future.delayed(const Duration(seconds: 5), () { completer.complete('Simulated Future Result'); }); return completer.future; } progressDialogue(BuildContext context) { AlertDialog alert = const AlertDialog( backgroundColor: Colors.transparent, elevation: 0, content: Center( child: CircularProgressIndicator(), ), ); showDialog( barrierDismissible: false, context: context, builder: (BuildContext context) { return PopScope( onPopInvoked: (didPop) async { return true; }, child: alert, ); }, ); }
说明
PopScope的onPopInvoked回调返回true时,会告知框架该弹出请求已被处理,不会执行默认的路由弹出操作- 保持
barrierDismissible: false确保点击弹窗外部不会关闭弹窗,和WillPopScope的行为一致
内容的提问来源于stack exchange,提问作者AG70
相关产品推荐
相关产品推荐

