【发布时间】:2020-09-28 08:44:12
【问题描述】:
我是 Flutter 和 Dart 的初学者,正在尝试构建一个使用 SQFLite 插件来持久化数据的待办事项列表应用程序。我有一个任务列表(自定义类的对象),并试图让用户(通过下拉菜单)选择特定类别的任务 - 类别 ID 存储为任务的属性。当我根据任务生成过滤列表并使用 setState 将我的类 taskList 设置为这个生成的列表时,它只是重新构建为整个类列表。我不知道这次重建是在哪里进行的。
我的 filterTasks 函数接受一个类别名称,识别它的类别 id - 如果用户正在清除过滤器,类别名称是 '' - 然后遍历所有任务以查找 id 匹配的位置(我意识到我可以也对数据库执行此操作,并选择所有 id 匹配的位置,但即使这意味着应该工作)如果有匹配项,那么它将显示的任务设置为这个过滤列表。
void filterTasks(String category) async {
await updateList(); //gets the entire list
print('Mid ${this.taskList}');
if (category != '') {
int filteredId = await getCategoryId(category);
List<Task> filtered = [];
int count = taskCount;
for (int i = 0; i < count; i++) {
if (this.taskList[i].taskCategory == filteredId) {
filtered.add(this.taskList[i]);
}
}
if (filtered.isEmpty) {
showSnackBar(context, "Error, no tasks of this category exist.", false);
setState(() {
categoryChoice = null;
});
} else {
setState(() {
this.taskList = filtered;
this.taskCount = this.taskList.length;
print('End ${this.taskList}');
});
}
}
}
更新列表功能只是从数据库中检索任务和类别的整个列表,因为用户可能希望直接在过滤器之间进行更改,而不必清理过滤器。我将它设置为等待,因为它是一个异步函数,并且我认为它可能会在完成此 filterTasks 函数后覆盖过滤列表。
这是我的构建函数的初始部分,如果 taskList 或 categoryList 为空,我将调用更新列表,这里不是这种情况。
Widget build(BuildContext context) {
print('Start ${this.taskList}');
if (taskList == null || categoryList == null) {
taskList = List<Task>();
categoryList = List<Category>();
updateList();
}
return Scaffold()//my widget tree
调用函数的下拉按钮代码:
DropdownButton(
hint: Text(
'Filter',
style: TextStyle(
color: textColor,
),
),
dropdownColor: bgColorPrimary,
value: categoryChoice,//class variable
items: this.categoryList?.map((Category instance) {
return DropdownMenuItem(
value: instance.categoryName,
child: Text(
instance.categoryName,
style: TextStyle(
color: categoryColorsMap[instance.categoryColour],
fontSize: 16.0),
));
})?.toList() ??
[],
onChanged: (newValue) {
filterTasks(newValue);
},
icon: Icon(
Icons.filter_list,
color: textColor,
),
)
过滤器列表由下拉按钮后面的另一个图标重置,该按钮简单地将 categoryChoice 设置为 null(以显示下拉提示)并使用参数 '' 调用 filterTasks。
编辑: 在修改了一些打印语句之后,特别是 4 个,其中 3 个在代码 sn-ps 中显示,一个在 updateList 函数的开头,我现在更感兴趣了。 updateList 中的 print 语句简单地说“已触发”,输出如下:
//APP BOOT UP
I/flutter (18734): Start null
I/flutter (18734): triggered
I/flutter (18734): Start [Instance of 'Task', Instance of 'Task', Instance of 'Task', Instance of 'Task']
//THIS IS WHEN I FILTERED THE TASKS
I/flutter (18734): triggered
I/flutter (18734): mid [Instance of 'Task', Instance of 'Task', Instance of 'Task', Instance of 'Task']
I/flutter (18734): End [Instance of 'Task', Instance of 'Task']
I/flutter (18734): Start [Instance of 'Task', Instance of 'Task']
I/flutter (18734): Start [Instance of 'Task', Instance of 'Task', Instance of 'Task', Instance of 'Task']
因此,当 taskList 得到更新时,并不是 updateList 使它恢复到整个列表。我根本无法弄清楚是什么。任何帮助将不胜感激,谢谢。
PS 我是 dart 的初学者,所以我并不完全熟悉命名约定和更精细的 OOP 细微差别,如果您对此有任何反馈,也请告诉我 :) 谢谢您的帮助。
【问题讨论】:
-
我怀疑它重建了整个小部件树,因为您的整个构建方法以在 setState() 中更改的条件开始。基本上 taskList 是您的入口点,从该行开始,下面的所有内容都将被重建。
-
一旦 filterTasks 方法运行并更新了 taskList,条件将不会正确传递(因为 categoryList 不为空)。
-
嗨,您将类别变量(传递给函数 filterTasks 的变量)存储在哪里?
-
所以这是一个通过下拉按钮更改的类变量!我使用 print 语句作为伪调试,传递给函数的类别是正确的!我将添加一个 sn-p 向您展示下拉菜单。