我有一个待办事项应用程序,它使用provider进行状态管理和sqlite数据库。

在应用程序中,我试图添加Dismissible小部件以删除项目。

但是问题是当我尝试删除项目时,它的确从database中删除了,但屏幕上出现错误。

sqlite - 被驳回的“可驳回”窗口小部件仍然是树状结构的一部分-LMLPHP


════════ Exception caught by widgets library ═══════════════════════════════════════════════════════
The following assertion was thrown building Dismissible-[<'howll'>](dirty, dependencies: [Directionality], state: _DismissibleState#98163(tickers: tracking 2 tickers)):
A dismissed Dismissible widget is still part of the tree.

Make sure to implement the onDismissed handler and to immediately remove the Dismissible
widget from the application once that handler has fired.
User-created ancestor of the error-causing widget was:
  TaskListTile file:///C:/Users/adity/Desktop/flutter-app/todoye/lib/widgets/task_list_view.dart:14:22
When the exception was thrown, this was the stack:
#0      _DismissibleState.build.<anonymous closure> (package:flutter/src/widgets/dismissible.dart:526:11)
#1      _DismissibleState.build (package:flutter/src/widgets/dismissible.dart:533:8)
#2      StatefulElement.build (package:flutter/src/widgets/framework.dart:4047:27)
#3      ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3941:15)
#4      Element.rebuild (package:flutter/src/widgets/framework.dart:3738:5)
...

这是我的代码。


Dismissible(
      key: Key(taskTitle),
      onDismissed: (direction) {
        deleteCallback();
        Scaffold.of(context)
            .showSnackBar(SnackBar(content: Text("$taskTitle removed.")));
      },
      child: ListTile(
           title: Text(
          '$taskTitle',
        ),


void deleteTask(int id) {
    taskDatabaseManager.deleteTask(id);
    notifyListeners();
  }


Future<void> deleteTask(int id) async {
    await openDb();
    await _database.delete(
      'tasks',
      where: 'id = ?',
      whereArgs: [id],
    );
  }


class TaskListView extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Consumer<TaskData>(
      builder: (context, taskData, child) {
        return ListView.builder(
            itemCount: taskData.taskCount,
            itemBuilder: (context, index) {
              return TaskListTile(
                taskTitle: taskData.tasks[index].name,
                isChecked: taskData.tasks[index].isDone,
                checkboxCallback: (checkboxState) {
                  taskData.updateTask(taskData.tasks[index]);
                },
                deleteCallback: () {
                  taskData.deleteTask(taskData.tasks[index].id);
                },
              );
            });
      },
    );
  }
}

最佳答案

消除Dismissible时,应将其从小部件树中删除。对于您的情况,您正在为Dismissible的每个项目显示一个taskData,因此,如果您取消某个项目的Dismissible,则应从列表中删除该项目。

因此,在deleteCallback中,在完成deleteTask()之后,您应该在taskData.removeAt(index)中执行setState()

10-01 07:34