未处理的异常:查找已停用小部件的祖先是不安全的。如何解决这个问题?

Posted

技术标签:

【中文标题】未处理的异常:查找已停用小部件的祖先是不安全的。如何解决这个问题?【英文标题】:Unhandled Exception: Looking up a deactivated widget's ancestor is unsafe. how to solve this? 【发布时间】:2022-01-11 22:14:51 【问题描述】:

我正在尝试将条纹支付集成到 Flutter 移动应用中。完成付款后,我希望应用程序执行 Navigator.pop(context)。但是,我收到一条错误消息,上面写着

“未处理的异常:查找已停用小部件的祖先是不安全的。 E/flutter (2773):此时小部件的元素树的状态不再稳定。”

这是我的条纹支付代码

class ExistingCardsPage extends StatefulWidget 
 static const String id = 'exsiting-card';
 ExistingCardsPage(Key key) : super(key: key);

 @override
 ExistingCardsPageState createState() => ExistingCardsPageState();


class ExistingCardsPageState extends State<ExistingCardsPage> 
 List cards = [];
 StripeService _service = StripeService();

 Future<StripeTransactionResponse> payViaExistingCard(
     BuildContext context, card, amount) async 
    await EasyLoading.show(status: "Please wait....");
    var expiryArr = card['expiryDate'].split('/');
    CreditCard stripeCard = CreditCard(
     number: card['cardNumber'],
     expMonth: int.parse(expiryArr[0]),
     expYear: int.parse(expiryArr[1]),
   );
   var response = await StripeService.payViaExistingCard(
      amount: '$amount00', currency: 'USD', card: stripeCard);
    await EasyLoading.dismiss();
    ScaffoldMessenger.of(context).showSnackBar(
       SnackBar(
         content: Text(response.message),
         duration: new Duration(milliseconds: response.success == true ? 1200 : 3000),
       )
   ).closed.then((_) 
     Navigator.pop(context); /////THIS IS THE ERROR/////

   );

   return response;


 @override
 Widget build(BuildContext context) 
   final orderProvider = Provider.of<OrderProvider>(context);
    return Scaffold(
     appBar: AppBar(
    iconTheme: IconThemeData(color: Colors.white),
    title: Text('Choose existing card', style: TextStyle(color: Colors.white),),
  ),
  body: FutureBuilder<QuerySnapshot>(
    future: _service.cards.get(),
    builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) 
      if (snapshot.hasError) 
        return Text('Something went wrong');
      

      if (snapshot.connectionState == ConnectionState.waiting) 
        return Center(child: CircularProgressIndicator());
      

      if(snapshot.data.size==0)
        return Center(
          child: Text('No Credit Card in your account'));
      

      return Container(
        padding: EdgeInsets.only(left: 8, top: 10, right: 8, bottom: 10),
        child: ListView.builder(
          itemCount: snapshot.data.docs.length,
          itemBuilder: (BuildContext context, int index) 
            var card = snapshot.data.docs[index];
            return InkWell(
              onTap: () 
                payViaExistingCard(context, card, orderProvider.amount).then((response) 
                  if(response.success==true)
                    orderProvider.paymentStatus(response.success);
                  
                );
              ,
              child: CreditCardWidget(
                cardNumber: card['cardNumber'],
                expiryDate: card['expiryDate'],
                cardHolderName: card['cardHolderName'],
                cvvCode: card['cvvCode'],
                showBackView: false,
                onCreditCardWidgetChange: (brand) 
                  print(brand);
                ,
              ),
            );
          ,
        ),
      );
    ,
  )
);


有人知道代码有什么问题吗?

谢谢

【问题讨论】:

【参考方案1】:

为 SnackBar 使用全局上下文

// declare as global
GlobalKey<ScaffoldMessengerState> scaffoldMessengerKey=GlobalKey<ScaffoldMessengerState>();

只需将此添加到main.dart 文件中

   @override
  Widget build(BuildContext context) 
    return MaterialApp(
      title: 'App Name',
      scaffoldMessengerKey: scaffoldMessengerKey, // add this
    );
  

然后我们可以在应用内的任何地方使用它,而无需传递每个页面上下文。

scaffoldMessengerKey.currentState.showSnackBar(SnackBar(
        content: Text(
          "Your Message",
        ),
      ));

【讨论】:

以上是关于未处理的异常:查找已停用小部件的祖先是不安全的。如何解决这个问题?的主要内容,如果未能解决你的问题,请参考以下文章

使用提供程序和快餐栏查找已停用小部件的祖先是不安全的

如果添加到动画列表,Flutter 查找已停用小部件的祖先是不安全的

提供者:查找已停用小部件的祖先是不安全的

Flutter:查找已停用小部件的祖先是不安全的

Flutter:错误是查找已停用小部件的祖先是不安全的

尝试使用谷歌地图时查找已停用小部件的祖先是不安全的