被解雇的 Dismissible 小部件仍然是颤动树的一部分
Posted
技术标签:
【中文标题】被解雇的 Dismissible 小部件仍然是颤动树的一部分【英文标题】:A dismissed Dismissible widget is still part of the tree in flutter 【发布时间】:2020-02-16 15:06:35 【问题描述】:我有一个使用provider
进行状态管理和sqlite
数据库的待办事项应用程序。
在应用程序中,我尝试添加 Dismissible
小部件以删除项目。
但问题是当我尝试删除项目时它确实从database
中删除但我在屏幕上收到错误。我是新来的。
控制台出错。
════════ 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);
,
);
);
,
);
【问题讨论】:
您可以将代码从 ListView 发布到 Dismissible 吗? 【参考方案1】:如果您确定您的可关闭小部件已被删除。尝试修复key
。
密钥应该是唯一的。如果tasks的id是唯一的,
key: Key(taskData.tasks[index].id)
如果您没有任何其他恒定且唯一的数据,您可以尝试
key: UniqueKey()
【讨论】:
【参考方案2】:当您关闭 Dismissible
时,您应该将其从小部件树中移除。在您的情况下,您为taskData
的每个项目显示Dismissible
,因此如果您关闭某个项目的Dismissible
,您应该从列表中删除该项目。
因此,在deleteCallback
中,在执行deleteTask()
之后,您应该在setState()
中执行taskData.removeAt(index)
。
【讨论】:
我有点困惑我应该将它们放在task_list_tile.dart
文件上的task_list_view.dart
文件中的哪个位置实际上我在task_list_view.dart
文件中使用Consumer
这就是原因。
在task_list_view.dart
中,因为在task_list_tile.dart
中您没有对索引或列表的引用。
但是那里说removeAt
没有定义。以上是关于被解雇的 Dismissible 小部件仍然是颤动树的一部分的主要内容,如果未能解决你的问题,请参考以下文章
Flutter Dismissible 小部件,带有 confirmDismiss 和 showAlertDialog 停止应用程序