Fondamentalement, j'essaie de créer une application dont le contenu sera mis à jour avec une fonction asynchrone qui prend des informations d'un site Web, mais lorsque j'essaie de définir le nouvel état, le contenu ne sera pas rechargé. Si je débogue l'application, cela montre que le contenu actuel est le nouveau, mais après avoir "reconstruit" tout le widget, il ne montre pas les nouvelles informations.
Edit: méthode loadData (), lit en principe une URL avec un package http, l’URL contient un fichier JSON dont le contenu change toutes les 5 minutes avec les nouvelles actualités. Par exemple, un fichier .json contenant des tableaux de bord sportifs en temps réel dont les scores changent constamment, de sorte que le contenu doit toujours changer avec les nouveaux résultats.
class mainWidget extends StatefulWidget
{
State<StatefulWidget> createState() => new mainWidgetState();
}
class mainWidgetState extends State<mainWidget>
{
List<Widget> _data;
Timer timer;
Widget build(BuildContext context) {
return new ListView(
children: _data);
}
@override
void initState() {
super.initState();
timer = new Timer.periodic(new Duration(seconds: 2), (Timer timer) async {
String s = await loadData();
this.setState(() {
_data = <Widget> [new childWidget(s)];
});
});
}
}
class childWidget extends StatefulWidget {
childWidget(String s){
_title = s;
}
Widget _title;
createState() => new childState();
}
class childState extends State<gameCardS> {
Widget _title;
@override
Widget build(BuildContext context) {
return new GestureDetector(onTap: foo(),
child: new Card(child: new Text(_title));
}
initState()
{
super.initState();
_title = widget._title;
}
}
Cela devrait régler votre problème. En gros, vous voulez toujours que vos widgets soient créés dans votre hiérarchie de méthodes build
.
import 'Dart:async';
import 'package:flutter/material.Dart';
void main() => runApp(new MaterialApp(home: new Scaffold(body: new MainWidget())));
class MainWidget extends StatefulWidget {
@override
State createState() => new MainWidgetState();
}
class MainWidgetState extends State<MainWidget> {
List<ItemData> _data = new List();
Timer timer;
Widget build(BuildContext context) {
return new ListView(children: _data.map((item) => new ChildWidget(item)).toList());
}
@override
void initState() {
super.initState();
timer = new Timer.periodic(new Duration(seconds: 2), (Timer timer) async {
ItemData data = await loadData();
this.setState(() {
_data = <ItemData>[data];
});
});
}
@override
void dispose() {
super.dispose();
timer.cancel();
}
static int testCount = 0;
Future<ItemData> loadData() async {
testCount++;
return new ItemData("Testing #$testCount");
}
}
class ChildWidget extends StatefulWidget {
ItemData _data;
ChildWidget(ItemData data) {
_data = data;
}
@override
State<ChildWidget> createState() => new ChildState();
}
class ChildState extends State<ChildWidget> {
@override
Widget build(BuildContext context) {
return new GestureDetector(onTap: () => foo(),
child: new Padding(
padding: const EdgeInsets.symmetric(vertical: 12.0, horizontal: 24.0),
child: new Card(
child: new Container(
padding: const EdgeInsets.all(8.0),
child: new Text(widget._data.title),
),
),
)
);
}
foo() {
print("Card Tapped: " + widget._data.toString());
}
}
class ItemData {
final String title;
ItemData(this.title);
@override
String toString() {
return 'ItemData{title: $title}';
}
}
ne pas utiliser un avenir dans un avenir; utiliser une fonction différente qui retournera chaque futur individuellement comme ceci
List<Requests> requestsData;
List<DocumentSnapshot> requestsDocumentData;
var docId;
@override
void initState() {
super.initState();
getRequestDocs();
}
Future<FirebaseUser> getData() {
var _auth = FirebaseAuth.instance;
return _auth.currentUser();
}
getRequestDocs() {
getData().then((FirebaseUser user) {
this.setState(() {
docId = user.uid;
});
});
FireDb()
.getDocuments("vendorsrequests")
.then((List<DocumentSnapshot> documentSnapshots) {
this.setState(() {
requestsDocumentData = documentSnapshots;
});
});
for (DocumentSnapshot request in requestsDocumentData) {
this.setState(() {
requestsData.add(Requests(
request.documentID,
request.data['requests'],
Icons.data_usage,
request.data['requests'][0],
"location",
"payMessage",
"budget",
"tokensRequired",
"date"));
});
}
}
vous pouvez créer des fonctions individuelles pour
FireDb().getDocuments("vendorsrequests")
.then((List<DocumentSnapshot> documentSnapshots) {
this.setState(() {
requestsDocumentData = documentSnapshots;
});
});
et
for (DocumentSnapshot request in requestsDocumentData) {
this.setState(() {
requestsData.add(Requests(
request.documentID,
request.data['requests'],
Icons.data_usage,
request.data['requests'][0],
"location",
"payMessage",
"budget",
"tokensRequired",
"date"));
});
}
J'ai trouvé que l'utilisation de
this
avec setState est indispensable