在页面渲染之前,我需要从三个不同的url获取数据。所以, 这是我的ScopedModel内的方法,其中包含多个http.post方法:
Future fetchData() async {
_isLoading = true;
notifyListeners();
await fetchAvailable();
await fetchOnProgress();
await fetchCompleted();
_isLoading = false;
notifyListeners();
}
fetchData区域内的方法只是具有原始Future类型的经典http.post请求。
这是我的FutureBuilder:
FutureBuilder(
future: model.fetchData(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
return snapshot.connectionState != ConnectionState.done
? Center(
child: CircularProgressIndicator(),
)
: Column.......
问题是“未来”功能,它不断执行且永无止境。我从服务器获取json的算法将正文中的变量膨胀为ListView.builder后代。
输出如我所说的递归发布请求。另外,我正在获取此日志,行数以1-2-3或2-4-6 -8等递增。
uid=10085(my.package.directory) 1.ui identical 1 lines
.......Other logs here
uid=10085(my.package.directory) 1.ui identical 3 lines
然后继续...
还有,还有其他有用的方法来处理页面呈现之前的少量数据吗?
答案 0 :(得分:2)
请勿在{{1}}中发出HTTP请求
https://docs.flutter.io/flutter/widgets/FutureBuilder-class.html
将来一定要早一些,例如中 State.initState,State.didUpdateConfig或 State.didChangeDependencies。不得在 构造状态时调用State.build或StatelessWidget.build方法 FutureBuilder。如果未来与 FutureBuilder,那么每次重新构建FutureBuilder的父项时, 异步任务将重新启动。
答案 1 :(得分:0)
这是一个可能的正确解决方案。这使您的数据仅在脚手架内加载一次。首先,请确保您使用的是有状态窗口小部件。
定义数据:
Future<List<Data>> futureList;
提供一个从后端获取数据的功能:
Future<void> getList() async {
final provider = Provider.of<DataProvider>(context, listen: false);
final list = provider.getData();
setState((){
futureList = list;
});
}
在初始化状态下加载函数:
@override
void initState() {
super.initState();
Future.delayed(Duration.zero, () {
getList();
});
}
在将来的构建器中调用您获取的数据:
Widget _body(BuildContext context) {
return FutureBuilder(
future: futureList,
builder: (BuildContext context, AsyncSnapshot<List> snapshot) {
if (snapshot.hasData) {
if(snapshot.data.length == 0){
return Center(child: Text('List is empty'));
}else {
return ListView.builder(
padding: EdgeInsets.only(left: 5, right: 5, top: 5, bottom: 5),
itemBuilder: (BuildContext context, int index) {
return GestureDetector(
child: DataItem(
index: index,
dataClass: snapshot.data[index],
),
onTap: () {});
},
itemCount: snapshot.data.length);
}
} else {
return Center(child: CircularProgressIndicator());
}
},
);