You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter Dismissible组件startToEnd滑动无法触发关闭问题求助

Dismissible组件startToEnd滑动无响应的解决方法

问题根源

你的confirmDismiss方法在处理startToEnd方向时,调用showDialog后没有返回明确的确认结果,且最后统一返回null,导致Dismissible无法判断是否允许执行关闭操作。而endToStart方向正确返回了showDialog的异步结果,因此功能正常。

另外,tasks列表直接定义在build方法中,每次组件重建都会重置列表内容,删除操作后刷新界面时列表会回到初始状态,需要将其移到State类的成员变量中。

修复后的代码

class TaskListW extends StatefulWidget {
  TaskListW({Key? key}) : super(key: key);

  @override
  State<TaskListW> createState() => _TaskListWState();
}
class _TaskListWState extends State<TaskListW> {
  // 将tasks移到State成员变量,避免每次build重置
  List tasks = ['task', 'task1', 'task2'];

  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(
      builder: (ctx, constraints) {
        return Column(
            mainAxisAlignment: MainAxisAlignment.start,
            mainAxisSize: MainAxisSize.min,
            children: [
              Expanded(
                flex: 1,
                child: ListView.builder(
                  scrollDirection: Axis.vertical,
                  itemCount: tasks.length,
                  itemBuilder: (ctx, index) {
                    return Dismissible(
                      child: TaskItem("1231241242", "DummyTask", "Social"),
                      key: ValueKey(tasks[index]),
                      direction: DismissDirection.horizontal,
                      background: Container(
                        color: Colors.orangeAccent,
                        child: Padding(
                          padding: const EdgeInsets.all(5),
                          child: Row(
                            children: const [
                              Text(
                                'Done',
                                style: TextStyle(color: Colors.black),
                              ),
                            ],
                          ),
                        ),
                      ),
                      secondaryBackground: Container(
                        color: Colors.redAccent,
                        child: Padding(
                          padding: const EdgeInsets.all(5),
                          child: Row(
                            mainAxisAlignment: MainAxisAlignment.end,
                            children: const [
                              Text(
                                'Delete',
                                style: TextStyle(color: Colors.white),
                              ),
                            ],
                          ),
                        ),
                      ),
                      onDismissed: (DismissDirection direction) {
                        if (direction == DismissDirection.startToEnd) {
                          print('Marked Completed');
                        } else {
                          print('Removed item');
                        }

                        setState(() {
                          tasks.removeAt(index);
                        });
                      },
                      confirmDismiss: (DismissDirection direction) async {
                        if (direction == DismissDirection.startToEnd) {
                          await showDialog(
                              context: context,
                              builder: (BuildContext context) {
                                return AlertDialog(
                                  title: const Text("Well Done!"),
                                  actions: [
                                    TextButton(
                                      onPressed: () => Navigator.of(context).pop(),
                                      child: const Text("OK"),
                                    )
                                  ],
                                );
                              });
                          // 返回true允许Dismissible执行关闭操作
                          return true;
                        } else {
                          return await showDialog(
                            context: context,
                            builder: (BuildContext context) {
                              return AlertDialog(
                                title: const Text("Delete Confirmation"),
                                content: const Text(
                                    "Are you sure you want to delete this item?"),
                                actions: <Widget>[
                                  TextButton(
                                      onPressed: () async {
                                        Navigator.of(context).pop(true);
                                      },
                                      child: const Text("Delete")),
                                  TextButton(
                                    onPressed: () =>
                                        Navigator.of(context).pop(false),
                                    child: const Text("Cancel"),
                                  ),
                                ],
                              );
                            },
                          );
                        }
                      },
                    );
                  },
                ),
              )
            ]);
      },
    );
  }
}

关键修改点

  • 将tasks列表从build方法移到State类的成员变量,确保状态修改后能正确保留。
  • 在confirmDismiss的startToEnd分支中,添加对话框的关闭按钮,并返回true(若需用户确认完成操作,可改成类似删除的确认对话框,返回用户选择的结果)。
  • 移除最后多余的return null,确保每个分支都返回明确的Future<bool>结果。

内容的提问来源于stack exchange,提问作者Maria Donosova

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 00:05:01