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

标签 dart flutter future dismissible

上下文:
我在测试 ListView 时偶然发现了一次轻微的崩溃。的 Dismissible在 flutter 中。滑动可关闭时,Dialog使用 confirmDismiss 显示选项,用于确认。这一切都很好,但是在测试不太可能的用例时 UI 崩溃。在页面上有几个选项可以导航到其他(命名)路线。当滑动可关闭时,并且在动画期间点击导航到新路线的选项时,就会发生崩溃。

如何复制崩溃:

  • 驳回驳回
  • 在接下来的动画中(可解散位置的翻译),点击一个 Action ,将您带到
    新路线。执行此操作的时间范围很短,我已在示例中对其进行了扩展。
  • 新路由加载和 UI 卡住

  • 作为引用,这是错误消息:

    AnimationController.reverse() called after AnimationController.dispose()



    罪魁祸首是动画在已经处理后试图反转:

    package:flutter/…/widgets/dismissible.dart:449



    我试过的东西:
    最初,我尝试检查 this.mountedshowDialog builder但很快意识到问题不在那里。
    另一个想法是通过使用 CancelableOperation.fromFuture 来规避这个问题。然后在 dispose() 中取消它包含小部件的方法,但这无济于事。

    我能做些什么来解决或至少规避这个问题?

    代码(也可以找到并克隆 here ):
    // (...)
    class _DimissibleListState extends State<DimissibleList> {
      int childSize = 3;
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: ListView.builder(
            itemCount: childSize,
            itemBuilder: (context, index) {
              if (index == 0) {
                return _buildNextPageAction(context);
              }
              return _buildDismissible();
            },
          ),
        );
      }
    
      Widget _buildNextPageAction(context) {
        return FlatButton(
          child: Text("Go to a new page"),
          onPressed: () => Navigator.of(context).pushNamed('/other'),
        );
      }
    
      Dismissible _buildDismissible() {
        GlobalKey key = GlobalKey();
    
        return Dismissible(
          key: key,
          child: ListTile(
            title: Container(
              padding: const EdgeInsets.all(8.0),
              color: Colors.red,
              child: Text("A dismissible. Nice."),
            ),
          ),
          confirmDismiss: (direction) async {
            await Future.delayed(const Duration(milliseconds: 100), () {});
            return showDialog(
              context: context,
              builder: (context) {
                return Dialog(
                  child: FlatButton(
                    onPressed: () => Navigator.of(context).pop(true),
                    child: Text("Confirm dismiss?"),
                  ),
                );
              },
            );
          },
          resizeDuration: null,
          onDismissed: (direction) => setState(() => childSize--),
        );
      }
    }
    

    最佳答案

    我在 confirmDismiss 上遇到了几乎相同的问题,在我的情况下,我在 confirmDismiss 中使用 (await Navigator.push() ) 导航到另一个屏幕,但作为返回,我遇到了这个错误:

    AnimationController.reverse() called after AnimationController.dispose()



    所以为了解决我在 confirmDismiss 中的问题,我在 confirmDismiss 之外调用了一个 future 函数(没有 await ),然后在该函数调用后添加 return true 或 false 以完成 confirmDismiss 的动画。

    关于dart - Dismissible confirmDismiss 结合新路由导航导致Flutter崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56166236/

    相关文章:

    flutter - 在 flutter 中为 SliverGrid 背景添加边框半径

    Flutter GestureDetector的onTapUp并不总是被调用

    javascript - Scala.js 中的 Future

    dart - Flutter/googleapis/Gmail API 发送电子邮件返回 400 Bad Request

    list - 从 For 语句向 Flutter 中的列表添加元素?

    xcode - Flutter 生成的 ios 文件版本控制

    javascript - Fluture bimap 和 fold,有什么区别,我应该什么时候使用它们?

    android - Navigator.pop 不会在 flutter 中关闭 simpledialog

    flutter - TabBar 和 ChangeNotifierProvider 的一个恼人的问题

    Scala Akka Play, future 不会回来