当前位置: 首页 > 知识库问答 >
问题:

不屑一顾和未来重建者不能一起工作

祁凯泽
2023-03-14
class TaskListState extends State<TaskList> {
  DBProvider dbProvider = new DBProvider();
  Future<List<Task>> allTasks;

  @override
  void initState() {
    allTasks = dbProvider.getAllTasks();
    super.initState();
  }

  void update(){
    setState(() {
      allTasks = dbProvider.getAllTasks();
    });
  }
  //build
}
  @override
  Widget build(BuildContext context) {
    return ListView(
      physics: const AlwaysScrollableScrollPhysics(),
      children: <Widget>[
        //other widgets such as a title for the list
        ),
        FutureBuilder(
          future: allTasks,
          builder: (context, snapshot){
            if(snapshot.hasError){
              return Text("Data has error.");
            } else if (!snapshot.hasData){
              return Center(
                child: CircularProgressIndicator(),
              );
            } else {
              return pendingList(Task.filterByDone(false, Task.filterByDate(Datetime.now, snapshot.data))); //filters the data to match current day
            }
          },
        ),
        //other widgets
      ],
    );
  }

pendingList

Widget pendingList(List<Task> tasks){
    //some code to return a Text widget if "tasks" is empty
    return ListView.separated(
      separatorBuilder: (context, index){
        return Divider(height: 2.0);
      },
      itemCount: tasks.length,
      physics: const NeverScrollableScrollPhysics(),
      shrinkWrap: true,
      itemBuilder: (context, index){
        return Dismissible(
          //dismissible backgrounds, other non-required parameters
          key: Key(UniqueKey().toString()),
          onDismissed: (direction) async {
            Task toRemove = tasks[index]; //save the dismissed task for the upcoming operations
            int removeIndex = tasks.indexWhere((task) => task.id == toRemove.id);
            tasks.removeAt(removeIndex); //remove the dismissed task
            if(direction == DismissDirection.endToStart) {
              rateTask(toRemove).then((value) => update()); //rateTask is a function that updates the task, it is removed from the list
            }
            if(direction == DismissDirection.startToEnd) {
              dbProvider.update(/*code to update selected task*/).then((value) => update());
            }

          },
          child: ListTile(
            //ListTile details
          ),
        );
      },
    );
  }

删除小部件实际上是将其从列表中删除。在用户取消任务后,该任务将从列表中“可视化地”删除,并调用update()方法,该方法调用setstate()。调用setstate()会导致FutureBuilder再次生成,但是在FutureBuilder再次生成时,dbProvider.getAllTasks()调用尚未完成。因此,FutureBuilder将传递旧快照,这将导致ListView使用刚刚被取消的任务再次生成。这导致被解雇的列表者在被解雇后暂时出现,这看起来令人毛骨悚然,也是错误的。

我不知道怎么解决这个问题。如有任何帮助,不胜感激。

共有1个答案

杜彦君
2023-03-14

我也遇到了同样的问题,我使用的sqflite与future一起工作,所以我最终使用了futurebuilderdismissible作为我的listview。删除的列表项将删除,然后在帧中重新出现,然后再次消失。我遇到这个问题:

return FutureBuilder<List<FolderModel>>(
      future: Provider.of<FoldersProvider>(context).getFolders(),
      builder: (context, snapshot) {
        if (!snapshot.hasData) {
          return Center(
            child: CircularProgressIndicator(),
          );
        }
        return ListView.builder(
          itemCount: snapshot.data.length,
          itemBuilder: (context, i) {
            final folder = snapshot.data[i];
            return Dismissible(
              onDismissed: (direction) {
                snapshot.data.removeAt(i); // to avoid weird future builder issue with dismissible
                Provider.of<FoldersProvider>(context, listen: false).deleteFolder(folder.id);
              },
              background: Card(
                margin: EdgeInsets.symmetric(vertical: 8),
                elevation: 1,
                child: Container(
                  alignment: AlignmentDirectional.centerStart,
                  color: Theme.of(context).accentColor,
                  child: Padding(
                    padding: EdgeInsets.fromLTRB(15.0, 0.0, 0.0, 0.0),
                    child: Icon(
                      Icons.delete,
                      color: Colors.white,
                    ),
                  ),
                ),
              ),
              key: UniqueKey(),
              direction: DismissDirection.startToEnd,
              child: Card(
                shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(15),
                ),
                margin: EdgeInsets.symmetric(vertical: 5, horizontal: 10),
                elevation: 1,
                child: ListTile(
                  title: Text(folder.folderName),
                  leading: Column(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: <Widget>[
                      Icon(
                        Icons.folder,
                        color: Theme.of(context).accentColor,
                      ),
                    ],
                  ),
                  subtitle: folder.numberOfLists != 1
                      ? Text('${folder.numberOfLists} items')
                      : Text('${folder.numberOfLists} item'),
                  onTap: () {},                  
                ),
              ),
            );
          },
        );
      },
    );
 类似资料:
  • {“时间戳”:1553613278534,“状态”:400,“错误”:“错误请求”,“消息”:“必需的字符串参数'param2'不存在”,“路径”:“/MyURL/42”} 我希望PUT的工作就像POST一样,但它似乎不是。 不幸的是,我不能将参数作为QueryParam发送,因此我应该维护相同的请求调用,因为我正在重构一个完全以这种方式工作的现有endpoint。

  • 当异常发生在CompletableFuture中时,我试图设置一个默认值,我通过如下方法使其工作: 但是,当我试图在不好的事情发生时异常地使用complete来停止CompletableFuture,并按如下方式跟踪异常时,我无法像刚才那样捕捉到异常。 更新日期2018-06-09谢谢您的帮助,@Daniele 在join()之前封闭的句柄按预期工作。但在这种情况下,

  • 我正在试验把杰克逊和龙目岛结合起来。这些是我的课: 这些是我添加到类spth中的JAR: > 龙目岛:https://projectlombok.org/downloads/lombok.jar(1.16.10version) 此外,Netbeans项目被配置为“保存时不编译”、“生成调试信息”、“报告不推荐使用的API”、“跟踪java依赖项”、“Activacte注释处理”和“编辑器中的Act

  • 更改单元格值后,我的不会刷新。我可以双击一个单元格并更改它的值,但是当我按OK或者我点击离开单元格时,值会重置为上一个,这不是更新表。这是我的自定义表模型的代码,我不知道如何更新数据库,因为当我改变单元格的值时,表是从一个db中取出来的。 如果您需要其他东西,例如数据库或表编辑器的代码,请告诉我;)谢谢您的帮助:) --编辑--好的,我已经实现了setValueAt方法,但是当我单击单元格时,它给

  • 更新后反序列化失败。 我将我的微服务从更新到,并将从更新为,从更新为。 JSON字符串- 班级 - 方法调用- 用于反序列化的方法 - 错误 -

  • 任何人都不知道这个错误意味着什么。