Dart Dismissible ConfirmDismise与新路线导航相结合会导致颤振碰撞
上下文:Dart Dismissible ConfirmDismise与新路线导航相结合会导致颤振碰撞,dart,flutter,future,dismissible,Dart,Flutter,Future,Dismissible,上下文: 我在颤振中测试Dismissibles的ListView时,偶然发现了一个小碰撞。刷取可驳回文件时,将显示一个对话框,使用confirmdismise选项进行确认。这一切都很好,但是当测试一个不太可能的用例时,UI崩溃了。页面上有几个选项可用于导航到其他(命名)路线。当一个dismissible被刷卡,并且在动画中点击了导航到新路线的选项时,就会发生崩溃 如何复制崩溃: 解雇可解雇的人 在随后的动画(可驳回的位置的平移)中,轻触将您带到 新路线。这样做的时间框架是最小的,我在示例中扩展
我在颤振中测试
Dismissible
s的ListView
时,偶然发现了一个小碰撞。刷取可驳回文件时,将显示一个对话框
,使用confirmdismise
选项进行确认。这一切都很好,但是当测试一个不太可能的用例时,UI崩溃了。页面上有几个选项可用于导航到其他(命名)路线。当一个dismissible被刷卡,并且在动画中点击了导航到新路线的选项时,就会发生崩溃
如何复制崩溃:起初,我尝试在showDialog builder中检查
this.mounted
,但很快意识到问题不在那里。另一个想法是通过使用
CancelableOperation.fromFuture
,然后在包含小部件的dispose()
方法中取消它来避免这个问题,但这是徒劳的
我能做些什么来解决或至少绕过这个问题
代码(也可以找到并克隆):
// (...)
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--),
);
}
}
/(…)
类_DimissibleListState扩展状态{
int childSize=3;
@凌驾
小部件构建(构建上下文){
返回脚手架(
正文:ListView.builder(
itemCount:childSize,
itemBuilder:(上下文,索引){
如果(索引==0){
返回_buildNextPageAction(上下文);
}
返回_buildDismissible();
},
),
);
}
小部件_buildNextPageAction(上下文){
返回按钮(
子项:文本(“转到新页”),
onPressed:()=>Navigator.of(context.pushName)('/other'),
);
}
可驳回的(Dismissible){
GlobalKey=GlobalKey();
可驳回的回报(
钥匙:钥匙,
孩子:ListTile(
标题:集装箱(
填充:常数边集全部(8.0),
颜色:颜色,红色,
孩子:文本(“一个不屑一顾的。很好。”),
),
),
确认解除:(方向)异步{
等待未来。延迟(常量持续时间(毫秒:100),({});
返回显示对话框(
上下文:上下文,
生成器:(上下文){
返回对话框(
孩子:扁平按钮(
onPressed:()=>Navigator.of(context.pop)(true),
子项:文本(“确认解除?”),
),
);
},
);
},
resizeDuration:null,
onDismissed:(方向)=>setState(()=>childSize--),
);
}
}
我在ConfirmDisease中遇到了几乎相同的问题,在我的例子中,我使用ConfirmDisease内部的(wait Navigator.push())导航到另一个屏幕,但作为回报,我遇到了以下错误:
在之后调用AnimationController.reverse()
AnimationController.dispose()
因此,为了解决ConfirmDisclease内部的问题,我在ConfirmDisclease外部调用了一个future函数(不等待),然后在该函数调用之后添加return true或false,以完成ConfirmDisclease的动画。您尝试过延迟导航吗?像500毫秒后的流行音乐?嘿@danypata这是一个有趣的思想链!但拖延并不能解决问题。现在,当用户返回带有listview的页面时,应用程序崩溃(错误保持不变)。我添加了一行“wait Future.delayed(const Duration(毫秒:100),(){};”,它对我有效。谢谢你问这个问题。