Flutter集成Stripe支付后导航报错:上下文已失效问题
问题描述
我做了一个BottomSheet,点击按钮即可关闭。但在Stripe支付场景中,若在调用presentPaymentSheet前执行Navigator.of(context).pop()关闭BottomSheet,完成Stripe支付表单提交后,当前上下文已不再活跃,无法跳转至新路由。
相关代码
// 1. create payment intent on the server final response = await http.post( Uri.parse( 'https://stripe//'), body: { 'email': email, 'amount': amount.toString(), }); final jsonResponse = jsonDecode(response.body); //log(jsonResponse.toString()); //2. initialize the payment sheet await stripe.Stripe.instance.initPaymentSheet( paymentSheetParameters: stripe.SetupPaymentSheetParameters( // Enable custom flow customFlow: true, // Main params paymentIntentClientSecret: jsonResponse['paymentIntent'], merchantDisplayName: 'GamRelay', // Customer keys customerId: jsonResponse['customer'], customerEphemeralKeySecret: jsonResponse['ephemeralKey'], // Extra options //applePay: true, //googlePay: true, style: ThemeMode.dark, //testEnv: true, //merchantCountryCode: 'SG', ), ); Navigator.of(context).pop(); await stripe.Stripe.instance.presentPaymentSheet(); Navigator.of(context).pushAndRemoveUntil( MaterialPageRoute(builder: (BuildContext context) => MainScreen()), (Route<dynamic> route) => false); Navigator.of(context).push(MaterialPageRoute( builder: (BuildContext context) => ShippingConfirmation()));
相关截图
- BottomSheet截图:

- 支付完成后报错截图:

解决方案
问题核心是关闭BottomSheet后,原context已绑定到被弹出的BottomSheet路由,不再属于活跃的上下文环境。以下两种方案可解决:
方案1:使用根导航器上下文
操作导航时指定rootNavigator: true,确保使用的是根导航器而非BottomSheet的局部导航上下文:
// 关闭BottomSheet时使用根导航器 Navigator.of(context, rootNavigator: true).pop(); await stripe.Stripe.instance.presentPaymentSheet(); // 路由跳转同样使用根导航器 Navigator.of(context, rootNavigator: true).pushAndRemoveUntil( MaterialPageRoute(builder: (BuildContext context) => MainScreen()), (Route<dynamic> route) => false); Navigator.of(context, rootNavigator: true).push(MaterialPageRoute( builder: (BuildContext context) => ShippingConfirmation()));
方案2:调整流程顺序
先完成支付操作,再关闭BottomSheet并跳转路由:
// 先执行支付,不提前关闭BottomSheet await stripe.Stripe.instance.presentPaymentSheet(); // 支付成功后再关闭BottomSheet并跳转 Navigator.of(context).pop(); Navigator.of(context).pushAndRemoveUntil( MaterialPageRoute(builder: (BuildContext context) => MainScreen()), (Route<dynamic> route) => false); Navigator.of(context).push(MaterialPageRoute( builder: (BuildContext context) => ShippingConfirmation()));
额外提示
你的代码中pushAndRemoveUntil已经移除所有前置路由并跳转到MainScreen,后续的push(ShippingConfirmation())大概率不会生效,建议调整路由逻辑——比如直接跳转至ShippingConfirmation并清除前置路由,或在MainScreen内部处理跳转逻辑。
内容的提问来源于stack exchange,提问作者alabiboo
相关产品推荐
相关产品推荐

