Android 14下Flutter+GoRouter返回键关闭应用而非回退页面求助
Android 14下Flutter GoRouter+PopScope系统返回键失效解决方案
针对你遇到的Android 14系统中,GoRouter结合PopScope时系统返回键直接最小化/关闭应用、无法回退上一页的问题,以下是经过验证的解决方案:
1. 升级GoRouter到最新稳定版
旧版本GoRouter对Android 14的预测性返回API支持存在兼容性bug,优先升级到>=12.0.0的稳定版本,官方后续迭代已经修复了不少相关问题。
2. 强制指定GoRouter的BackButtonDispatcher
在GoRouter初始化时,手动配置backButtonDispatcher为RootBackButtonDispatcher,接管返回键事件处理,避免系统预测性返回拦截路由逻辑:
GoRouter router = GoRouter( initialLocation: LoginScreen.routeName, debugLogDiagnostics: true, backButtonDispatcher: RootBackButtonDispatcher(), // 新增此行 routes: <RouteBase>[ // 你的路由配置 GoRoute( path: LoginScreen.routeName, name: LoginScreen.title, pageBuilder: (context, state) => MaterialPage<void>( key: state.pageKey, child: const LoginScreen(), ), ), GoRoute( path: PinScreen.routeName, name: PinScreen.title, pageBuilder: (context, state) => MaterialPage<void>( key: state.pageKey, child: const PinScreen(), ), ), ], );
3. 调整PopScope的实现逻辑
Android 14下PopScope的回调触发逻辑有变化,确保每个页面的PopScope配置正确:
class PinScreen extends StatelessWidget { const PinScreen({super.key}); @override Widget build(BuildContext context) { return PopScope( canPop: true, // 允许页面回退 onPopInvoked: (didPop) { if (didPop) return; // 系统已处理回退时直接返回 // 手动触发路由回退,可在此添加自定义确认逻辑 context.pop(); }, child: Scaffold( // 页面内容 ), ); } }
注意:必须确保canPop设为true,并且在onPopInvoked中手动调用context.pop()触发路由栈回退。
4. 禁用Android原生预测性返回
在Android项目的AndroidManifest.xml中,给MainActivity添加属性,关闭系统原生的预测性返回功能:
<activity android:name=".MainActivity" android:exported="true" android:launchMode="singleTop" android:theme="@style/LaunchTheme" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:hardwareAccelerated="true" android:windowSoftInputMode="adjustResize" android:enableOnBackInvokedCallback="false"> <!-- 新增此行 -->
5. 检查路由跳转方式
确认页面跳转使用context.push()而非context.go(),前者会将页面添加到路由栈,后者会替换当前路由,导致没有上一页可回退:
// 正确:添加到路由栈,支持返回 context.push(PinScreen.routeName); // 错误:替换当前路由,无回退栈 // context.go(PinScreen.routeName);
如果以上方案都无效,尝试执行flutter clean清空缓存后重新编译,或在debug模式下通过GoRouter的日志(开启debugLogDiagnostics: true)查看路由栈的变化,排查是否存在路由未正确入栈的情况。
内容的提问来源于stack exchange,提问作者REMASTERED1
相关产品推荐
相关产品推荐

