Flutter Dismissible 小部件,带有 confirmDismiss 和 showAlertDialog 停止应用程序

Posted

技术标签:

【中文标题】Flutter Dismissible 小部件,带有 confirmDismiss 和 showAlertDialog 停止应用程序【英文标题】:Flutter Dismissible widget with confirmDismiss and showAlertDialog stop app 【发布时间】:2020-02-10 02:47:56 【问题描述】:

当我尝试在带有 showAlertDialog 的 Dismissible 小部件上使用 confirmDismiss 时,它会弹出警报,但也会引发异常并停止应用程序。如果我尝试在异常后继续,它可以正常工作。

Maybe similar to this question 我试过用 showAlertDialog 来分离函数和不同类型的调用导航,但没有一个能解决它。

            Dismissible(
              confirmDismiss: (direction) 
                return showDialog(
                  context: context,
                  builder: (context) 
                    return CupertinoAlertDialog(
                      title: Text('Delete'),
                      content: Text('Delete'),
                      actions: <Widget>[
                        FlatButton(
                          onPressed: () 
                            // Navigator.pop(context, false);
                            Navigator.of(
                              context,
                              // rootNavigator: true,
                            ).pop(false);
                          ,
                          child: Text('No'),
                        ),
                        FlatButton(
                          onPressed: () 
                            // Navigator.pop(context, true);
                            Navigator.of(
                              context,
                              // rootNavigator: true,
                            ).pop(true);
                          ,
                          child: Text('Yes'),
                        ),
                      ],
                    );
                  ,
                );
              ,
              key: Key(UniqueKey().toString()),
              direction: DismissDirection.endToStart,
              onDismissed: (direction) 
                //TODO DELETE
                Scaffold.of(context).showSnackBar(
                  SnackBar(
                    backgroundColor: Theme.of(context).accentColor,
                    content: Text(
                      'test',
                      textAlign: TextAlign.center,
                      style: TextStyle(
                        fontSize: 20.0,
                        color: Colors.white,
                      ),
                    ),
                  ),
                );
              ,
              background: Container(
                padding: const EdgeInsets.only(right: 20.0),
                // alignment: AlignmentDirectional.centerEnd,
                alignment: Alignment.centerRight,
                color: Theme.of(context).accentColor,
                child: Icon(
                  Icons.delete,
                  size: 32.0,
                  color: Theme.of(context).primaryColor,
                ),
              ),
              child: Padding(
                padding: const EdgeInsets.symmetric(horizontal: 20.0),
                child: CartCard(),
              ),
            ),

这是个例外

[VERBOSE-2:ui_dart_state.cc(148)] Unhandled Exception: 'package:flutter/src/animation/animation_controller.dart': Failed assertion: line 484 pos 7: '_ticker != null': AnimationController.reverse() called after AnimationController.dispose()
AnimationController methods should not be used after calling dispose.
#0      _AssertionError._doThrowNew  (dart:core-patch/errors_patch.dart:40:39)
#1      _AssertionError._throwNew  (dart:core-patch/errors_patch.dart:36:5)
#2      AnimationController.reverse 
package:flutter/…/animation/animation_controller.dart:484
#3      _DismissibleState._handleDismissStatusChanged 
package:flutter/…/widgets/dismissible.dart:449
<asynchronous suspension>
#4      AnimationLocalStatusListenersMixin.notifyStatusListeners 
package:flutter/…/animation/listener_helpers.dart:193
#5      AnimationController._checkStatusChanged 
package:flutter/…/animation/animation_controller.dart:753
#6      AnimationController._tick (package:flutter/src/animation/animation_contr<…>

【问题讨论】:

我还没有用相同的代码确认,但这与CupertinoTabView有关,使用key: ValueKey(yourItem),可以解决这个问题。我来自here 【参考方案1】:

您的问题不在于解雇或确认解雇方法。错误警告很明确:您的问题与动画控制器有关。

显然,在您的代码中某处,您正在处理它 - 很可能在:

 @override dispose 

尝试删除它,看看它是否有效。

好的,试试这个

        Dismissible(
          confirmDismiss: (direction) 
            return showDialog(
              context: context,
              builder: (context) 
                return CupertinoAlertDialog(
                  title: Text('Delete'),
                  content: Text('Delete'),
                  actions: <Widget>[
                    FlatButton(
                      onPressed: () 
                        // Navigator.pop(context, false);
                        Navigator.of(
                          context,
                          // rootNavigator: true,
                        ).pop(false);
                      ,
                      child: Text('No'),
                    ),
                    FlatButton(
                      onPressed: () 
                        // Navigator.pop(context, true);
                        Navigator.of(
                          context,
                          // rootNavigator: true,
                        ).pop(true);
                      ,
                      child: Text('Yes'),
                    ),
                  ],
                );
              ,
            );
          ,
          key: UniqueKey(),
          direction: DismissDirection.endToStart,
          onDismissed: (direction) 
            //TODO DELETE
            Scaffold.of(context).showSnackBar(
              SnackBar(
                backgroundColor: Theme.of(context).accentColor,
                content: Text(
                  'test',
                  textAlign: TextAlign.center,
                  style: TextStyle(
                    fontSize: 20.0,
                    color: Colors.white,
                  ),
                ),
              ),
            );
          ,
          background: Container(
            padding: const EdgeInsets.only(right: 20.0),
            // alignment: AlignmentDirectional.centerEnd,
            alignment: Alignment.centerRight,
            color: Theme.of(context).accentColor,
            child: Icon(
              Icons.delete,
              size: 32.0,
              color: Theme.of(context).primaryColor,
            ),
          ),
          child: Padding(
            padding: const EdgeInsets.symmetric(horizontal: 20.0),
            child: CartCard(),
          ),
        ),

【讨论】:

感谢您的回答,但我没有使用任何 dispose 方法。我不确定,但我认为这个动画控制器连接到关闭小部件,而不是我自己的动画 我更新了我的评论,但你同意你在某处有一个动画控制器??对吗? 感谢您的评论,但它不起作用。抱歉我的解释不好,我的意思是关闭小部件本身包含动画控制器,但我没有添加任何额外的控制器。 我在这个关闭例程中没有看到对动画控制器的任何引用。都粘贴了吗? 我做到了。 DismissibleState 包含一个动画控制器来控制解除手势及其动画。【参考方案2】:

你需要做的就是写一个例如函数

Future<bool> sample(DismissDirection direction) async
   #write you code
   return true or false;

对我有用

【讨论】:

以上是关于Flutter Dismissible 小部件,带有 confirmDismiss 和 showAlertDialog 停止应用程序的主要内容,如果未能解决你的问题,请参考以下文章

被解雇的 Dismissible 小部件仍然是颤动树的一部分

Dismissible confirmDismiss 结合新的路由导航导致 Flutter 崩溃

如何解决'已关闭的可关闭小部件仍是树的一部分。'颤抖中

使用 Flutter/Dart 关闭 Dismissible

Dismissible 和 FutureBuilder 不能一起工作

Flutter Dismissible 未从树中移除