Je voudrais rendre un widget qui a besoin d'un appel HTTP pour collecter certaines données.
J'ai obtenu le code suivant (simplifié)
import 'package:flutter/material.dart';
import 'dart:async';
import 'dart:convert';
void main() {
runApp(new MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new MyHomePage(title: 'async demo'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
var asyncWidget;
@override
initState() {
super.initState();
loadData().then((result) {
print(result);
setState(() {
asyncWidget = result;
});
});
}
loadData() async {
var widget = new AsyncWidget();
return widget.build();
}
@override
Widget build(BuildContext context) {
if(asyncWidget == null) {
return new Scaffold(
appBar: new AppBar(
title: new Text("Loading..."),
),
);
} else {
return new Scaffold(
appBar: new AppBar(
title: new Text(widget.title),
),
body: new Center(
child: this.asyncWidget,
),
);
}
}
}
class MyRenderer {
MyRenderer();
Widget render (List data) {
List<Widget> renderedWidgets = new List<Widget>();
data.forEach((element) {
renderedWidgets.add(new ListTile(
title: new Text("one element"),
subtitle: new Text(element.toString()),
));
});
var lv = new ListView(
children: renderedWidgets,
);
return lv;
}
}
class MyCollector {
Future gather() async {
var response = await // do the http request here;
return response.body;
}
}
class AsyncWidget {
MyCollector collector;
MyRenderer renderer;
AsyncWidget() {
this.collector = new MyCollector();
this.renderer = new MyRenderer();
}
Widget build() {
var data = this.collector.gather();
data.then((response) {
var responseObject = JSON.decode(response);
print(response);
return this.renderer.render(responseObject);
});
data.catchError((error) {
return new Text("Oups");
});
}
}
Mon code fonctionne comme suit : le widget utilisant des données asynchrones prend un collecteur (qui fait l'appel http) et un moteur de rendu qui rendra les widgets avec les données http. Je crée une instance de ce widget lors de la fonction initState() et ensuite je fais mon appel asynchrone.
J'ai trouvé de la documentation indiquant que nous devrions utiliser la méthode setState() pour mettre à jour le widget avec les nouvelles données, mais cela ne fonctionne pas pour moi.
Cependant, lorsque j'enregistre des journaux, je vois que l'appel HTTP est effectué et que la méthode setState() est appelée, mais le widget ne se met pas à jour.
1 votes
Duplicata possible de Firestore async load et populate listview flutter