Flutter Dismissible和FutureBuilder不能一起工作

Flutter Dismissible和FutureBuilder不能一起工作,flutter,dart,future,sqflite,dismissible,Flutter,Dart,Future,Sqflite,Dismissible,这是一个复杂的问题,但我会尽力解释 我的项目使用一个sqflite数据库。此特定页面根据数据库中的数据返回一个可拒绝的小部件列表。以下是我读取数据的方式: 类TaskListState扩展状态{ DBProvider DBProvider=新的DBProvider(); 未来所有任务; @凌驾 void initState(){ allTasks=dbProvider.getAllTasks(); super.initState(); } 无效更新(){ 设置状态(){ allTasks=dbP

这是一个复杂的问题,但我会尽力解释

我的项目使用一个sqflite数据库。此特定页面根据数据库中的数据返回一个可拒绝的小部件列表。以下是我读取数据的方式:

类TaskListState扩展状态{
DBProvider DBProvider=新的DBProvider();
未来所有任务;
@凌驾
void initState(){
allTasks=dbProvider.getAllTasks();
super.initState();
}
无效更新(){
设置状态(){
allTasks=dbProvider.getAllTasks();
});
}
//建造
}
TaskList小部件返回一个带有FutureBuilder的页面,FutureBuilder使用数据库中的数据构建ListView.builder。ListView构建可忽略的小部件。解除可解除的小部件将更新数据库中的一行,并再次读取数据以更新列表

TaskListState的生成方法

@覆盖
小部件构建(构建上下文){
返回列表视图(
物理:常量AlwaysScrollablePhysics(),
儿童:[
//其他小部件,例如列表的标题
),
未来建设者(
未来:所有任务,
生成器:(上下文,快照){
if(snapshot.hasError){
返回文本(“数据有错误”);
}如果(!snapshot.hasData){
返回中心(
子对象:CircularProgressIndicator(),
);
}否则{
return pendingList(Task.filterByDone(false,Task.filterByDate(Datetime.now,snapshot.data));//过滤数据以匹配当前日期
}
},
),
//其他小部件
],
);
}
悬而未决的名单

Widget挂起列表(列出任务){
//如果“任务”为空,则返回文本小部件的一些代码
返回ListView.separated(
separatorBuilder:(上下文,索引){
回流隔板(高度:2.0);
},
itemCount:tasks.length,
物理学:const NeverScrollableScrollPhysics(),
收缩膜:对,
itemBuilder:(上下文,索引){
可驳回的回报(
//可驳回的背景、其他非必需参数
key:key(UniqueKey().toString()),
onDismissed:(方向)异步{
Task toRemove=tasks[index];//保存已解除的任务,以便进行后续操作
int removeIndex=tasks.indexWhere((task)=>task.id==toRemove.id);
tasks.removeAt(removeIndex);//删除已解除的任务
if(direction==DismissDirection.endToStart){
rateTask(toRemove)。然后((value)=>update());//rateTask是更新任务的函数,它将从列表中删除
}
如果(方向==解除方向.开始结束){
dbProvider.update(/*用于更新所选任务的代码*/)。然后((值)=>update());
}
},
孩子:ListTile(
//列表块详细信息
),
);
},
);
}
问题是(可能是错误的解释,我还是个新手):

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


我不知道如何解决这个问题。任何帮助都将不胜感激。

通过不使用FutureBuilder并在查询完成后调用setState找到了解决方法

该状态现在包含一个声明为空的
列表,而不是
Future

类TaskListState扩展状态{
DBProvider DBProvider=新的DBProvider();
DateTime now=DateTime.now();
列出今天的任务;
//建造
}
update()
函数更改如下

void update()异步{
Future futureTasks=dbProvider.getByDate(现在);//首先进行查询
未来任务。然后((数据){
列表任务=新列表();
对于(int i=0;i
这样我就可以在未来完成之前不重建小部件,这就是我遇到的问题

我完全删除了FutureBuilder,Listview.builder只是根据状态中存储的列表进行构建

@覆盖
小部件构建(构建上下文){
如果(TodayStasks==null){
更新();
返回中心(
子对象:CircularProgressIndicator(),
);
}//如果列表尚未初始化,则进行查询
返回列表视图(
物理:常量AlwaysScrollablePhysics(),
儿童:[
//其他小部件
pendingList(Task.filterByDone(false,TodayStasks)),
],
);
}

这种方法完全解决了我的问题,而且我认为它比使用FutureBuilder要好,以防将来必须在小部件再次构建之前完成

我遇到了完全相同的问题,我使用了sqflite,它与
期货
一起使用
FutureBuilder
Dismissible
一起用于我的
列表视图
。被删除的列表项将被删除,然后重新出现一帧,然后再次消失。我遇到了一个问题:

这建议从快照数据本身中删除列表项:

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: () {},                  
                ),
              ),
            );
          },
        );
      },
    );
返回FutureBuilder(
未来:供应商。