当我更改特定的futurebuilder小部件所依赖的状态时,直到异步任务完成后才重绘该小部件。我希望状态更改后立即重绘该小部件。以下是futurebuilder的代码:
child: new FutureBuilder(
future: _api.getListOfTourneys(searchTerm, filterChecks, pageNum),
builder: (context, snapshot) {
if (snapshot.hasData) {
if(!(snapshot.data is List)){
return new TourneyItem(snapshot.data['tournament']);
}
return new Expanded(
child: ListView.builder(
shrinkWrap: false,
scrollDirection: Axis.vertical,
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int index) {
return TourneyItem(snapshot.data[index]);
},
));
} else if (snapshot.hasError) {
return new Text("No results found");
} else {
return new CircularProgressIndicator();
}
},
)
答案 0 :(得分:2)
我认为FutureBuilder在启动时只构建一次,然后每次执行异步任务时都会构建。 因此,当我们导航至屏幕FutureBuilder是在开始时构建的,然后在异步任务完成时,则对于其他调用(首先除外),FutureBuilder仅在异步任务完成后构建。
我还需要在异步调用开始时重建FutureBuilder,我使用snapshot.connectionState
FutureBuilder的内部构建器
if(snapshot.connectionState == ConnectionState.done){
if(snapshot.hasData){
//Show data here
}else{
//Show error here
}
}else{
//Show progress
}
答案 1 :(得分:2)
您不能使用FutureBuilder做到这一点。如果您要构建的不仅仅是“初始” +“完成”,请不要使用FutureBuilder。
相反,您可以通过将将来的结果提交到流中来使用Stream
和StreamBuilder
。
class Foo extends StatefulWidget {
@override
_FooState createState() => _FooState();
}
class _FooState extends State<Foo> {
StreamController streamController;
@override
void initState() {
load();
super.initState();
}
load() async {
streamController.add("Loading");
await Future.delayed(Duration(seconds: 1));
streamController.add("Done");
}
@override
void didUpdateWidget(Foo oldWidget) {
if (somethingChanged) {
load();
}
super.didUpdateWidget(oldWidget);
}
@override
void dispose() {
streamController.close();
super.dispose();
}
@override
Widget build(BuildContext context) {
return StreamBuilder<String>(
stream: streamController.stream,
builder: (context, snapshot) {
if (snapshot.hasData) {
return new Text(snapshot.data);
} else if (snapshot.hasError) {
return new Text("Error");
} else {
return new Text("Nothing");
}
},
);
}
}
答案 2 :(得分:-1)
这有点晚了,但它对我有用,只需用相同的屏幕替换屏幕
Navigator.pushReplacement(context,
MaterialPageRoute(
builder: (BuildContext context) =>
*SamePage*()
)
);
不要在 showdialog 中使用此方法以避免在同一页面上返回两次!