Flutter 如何修复FutureBuilder中的递归HTTP请求?
我正在创建一个在屏幕中有列表的应用程序。我想做的是,每当应用程序发出HTTP请求(获取数据)时,我都想在屏幕上显示Flutter 如何修复FutureBuilder中的递归HTTP请求?,flutter,Flutter,我正在创建一个在屏幕中有列表的应用程序。我想做的是,每当应用程序发出HTTP请求(获取数据)时,我都想在屏幕上显示CircularProgressIndicator()。我试图使用FutureBuilder来实现这一点,但应用程序递归/连续地加载数据(设置ListView时,应用程序会一次又一次地加载数据)。以下是我的一些代码: FutureBuilder小部件 Widget _buildFuture(BuildContext context){ return FutureBuilder
CircularProgressIndicator()
。我试图使用FutureBuilder
来实现这一点,但应用程序递归/连续地加载数据(设置ListView
时,应用程序会一次又一次地加载数据)。以下是我的一些代码:
FutureBuilder小部件
Widget _buildFuture(BuildContext context){
return FutureBuilder(
future: listenForBeers(),
builder: (context, snapshot) {
if(snapshot.connectionState == ConnectionState.done){
if(snapshot.hasError){
print('_buildFuture: Loading error');
return Center(
child: Text(
snapshot.error.toString(),
textAlign: TextAlign.center,
textScaleFactor: 1.3,
),
);
}
print('_buildFuture: Showing the Data');
return _buildBeers();
}
else{
print('_buildFuture: Loading the data');
return Center(
child: Column(
children: <Widget>[
SizedBox(height: 100),
CircularProgressIndicator()
],
),
);
}
}
);
}
Widget\u buildFuture(BuildContext){
回归未来建设者(
future:listenForBeers(),
生成器:(上下文,快照){
if(snapshot.connectionState==connectionState.done){
if(snapshot.hasError){
打印(“U buildFuture:加载错误”);
返回中心(
子:文本(
snapshot.error.toString(),
textAlign:textAlign.center,
textScaleFactor:1.3,
),
);
}
打印(“U buildFuture:显示数据”);
返回_buildBeers();
}
否则{
打印(“U buildFuture:加载数据”);
返回中心(
子:列(
儿童:[
尺寸箱(高度:100),
循环推进指示器()
],
),
);
}
}
);
}
initState()和listenForBeers()方法
@override
void initState(){
super.initState();
listenForBeers();
}
Future listenForBeers() async {
final Stream<Beer> stream = await getBeers();
stream.listen((Beer beer) => setState(() => _beers.add(beer)));
}
Future<Stream<Beer>> getBeers() async {
final String url = 'https://api.punkapi.com/v2/beers';
final client = new http.Client();
final streamedRest = await client.send(http.Request('get', Uri.parse(url)));
return streamedRest.stream
.transform(utf8.decoder)
.transform(json.decoder)
.expand((data) => (data as List))
.map((data) => Beer.fromJSON(data));
}
@覆盖
void initState(){
super.initState();
listenForBeers();
}
Future listenForBeers()异步{
最终流=等待getBeers();
stream.listen((啤酒)=>setState(()=>u beers.add(啤酒));
}
getBeers()方法
@override
void initState(){
super.initState();
listenForBeers();
}
Future listenForBeers() async {
final Stream<Beer> stream = await getBeers();
stream.listen((Beer beer) => setState(() => _beers.add(beer)));
}
Future<Stream<Beer>> getBeers() async {
final String url = 'https://api.punkapi.com/v2/beers';
final client = new http.Client();
final streamedRest = await client.send(http.Request('get', Uri.parse(url)));
return streamedRest.stream
.transform(utf8.decoder)
.transform(json.decoder)
.expand((data) => (data as List))
.map((data) => Beer.fromJSON(data));
}
Future getBeers()异步{
最终字符串url=https://api.punkapi.com/v2/beers';
final client=new http.client();
final streamdrest=wait client.send(http.Request('get',Uri.parse(url));
返回流
.变换(utf8.解码器)
.transform(json.decoder)
.展开((数据)=>(数据作为列表))
.map((数据)=>Beer.fromJSON(数据));
}
我不确定如何以正确的方式实现,因为我对颤振也是新手。如果您需要其他代码,请随时询问,任何帮助都将不胜感激。谢谢 在状态类中创建异步备忘录生成器
AsyncMemoizer _memoizer = AsyncMemoizer();
现在改变
Future listenForBeers() async {
return this._memoizer.runOnce(() async {
final Stream<Beer> stream = await getBeers();
stream.listen((Beer beer) => setState(() => _beers.add(beer)));
)};
}
Future refreshBeers() async {
_memoizer = AsyncMemoizer();
return listenForBeers();
}
Future listenForBeers()异步{
返回此值。\ u memoizer.runOnce(()异步{
最终流=等待getBeers();
stream.listen((啤酒)=>setState(()=>u beers.add(啤酒));
)};
}
Future refreshBeers()异步{
_记忆器=异步记忆器();
返回listenForBeers();
}
详细信息请参见在initstate中初始化流,并保持如下引用
Stream<Beer> stream;
@override
void initState(){
super.initState();
stream = await getBeers();
stream.listen((Beer beer) => setState(() => _beers.add(beer)));
}
溪流;
@凌驾
void initState(){
super.initState();
stream=wait getBeers();
stream.listen((啤酒)=>setState(()=>u beers.add(啤酒));
}
可能会有帮助,谢谢您它工作得非常好,但是如果我实现了类似刷新视图的功能,我仍然可以调用该函数吗?对于调用刷新,只需调用_memoizer=asyncmomeizer();方法中的一次