Уволенный виджет Dismissible все еще является частью трепетающего дерева - PullRequest
0 голосов
/ 20 октября 2019

У меня есть приложение todo, которое использует provider для управления состоянием и sqlite база данных.

В приложении я пытаюсь добавить виджет Dismissible для удаления элемента.

Но проблема в том, что когда я пытаюсь удалить элемент, он действительно удаляется из database, но я получаю сообщение об ошибке на экране. Я плохо знаком с флаттером.

dismissible image

ошибка в консоли.

════════ 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)
...

Это мой код.

task_list_tile.dart

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

task_data.dart

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

databse_connection.dart

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

task_list_view.dart

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);
                },
              );
            });
      },
    );
  }
}

1 Ответ

1 голос
/ 20 октября 2019

Когда вы отклоняете Dismissible, вы должны удалить его из дерева виджетов. В вашем случае вы показываете Dismissible для каждого элемента taskData, поэтому, если вы отклоните Dismissible элемента, вы должны удалить этот элемент из списка.

Итак, в deleteCallback, после выполнения deleteTask(), вы должны сделать taskData.removeAt(index) внутри setState().

...