【发布时间】:2019-10-03 14:16:51
【问题描述】:
上下文:
我在 Flutter 中测试Dismissibles 中的ListView 时偶然发现了一次小崩溃。滑动可关闭项时,使用confirmDismiss 选项显示Dialog 以进行确认。这一切都很好,但是在测试不太可能的用例时 UI 会崩溃。页面上有几个选项可以导航到其他(命名的)路线。当轻扫可关闭的对象时,并且在动画期间点击导航到新路线的选项时,会发生崩溃。
如何复制崩溃:
- 解雇被解雇的人
- 在随后的动画(可关闭位置的平移)中,点击一个动作,将您带到 新路线。执行此操作的时间范围很短,我在示例中对其进行了扩展。
- 新路由加载,UI 冻结
作为参考,这是错误信息:
AnimationController.reverse() 在 AnimationController.dispose() 之后调用
罪魁祸首是动画在它已经被释放时试图反转:
我尝试过的事情:
最初,我尝试在showDialog builder 中检查this.mounted,但很快意识到问题不在于那里。
另一个想法是通过使用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--),
);
}
}
【问题讨论】:
-
您是否尝试过延迟导航?就像 500 毫秒后弹出一样?
-
嘿@danypata,这是一个有趣的思路!但是延迟并没有解决问题。现在当用户返回到带有列表视图的页面时应用程序崩溃(并且错误保持不变)
-
我添加了一行“await Future.delayed(const Duration(milliseconds: 100), () {});”,它对我有用。感谢您提出这个问题。
标签: dart flutter future dismissible