如何在自动从消防仓库获取数据后启动状态



我是flutter的初学者,正在我的应用程序中开发历史页面,我想做的是从Firestore中获取数据,然后处理这些数据并将其存储到一个列表中,这样我就可以在dashbord小部件中构建我的历史项目,问题是,除非我手动刷新状态,否则这些项目不会出现。在我使用这个过滤器图标的情况下,获取我数据的函数是getVente((,我在initState((中调用它,我希望这个动作在我加载页面的那一刻执行,项目也是如此,而不是手动执行。这是发生的事情图片gif

这是代码

import 'package:flutter/material.dart';
import 'package:rflutter_alert/rflutter_alert.dart';
import 'package:chips_choice/chips_choice.dart';
import 'package:stocknsell/Components/DownSelect.dart';
import 'package:stocknsell/Components/DownSelect2.dart';
import 'package:date_range_picker/date_range_picker.dart' as DateRagePicker;
import 'package:stocknsell/Components/historyitem.dart';
final Color backgroundColor = Color(0xFF4A4A58);
class HistoriquePage extends StatefulWidget {
static String id = "/history";
@override
_HistoriquePageState createState() => _HistoriquePageState();
}
class _HistoriquePageState extends State<HistoriquePage>
with SingleTickerProviderStateMixin {
bool isCollapsed = true;
double screenWidth, screenHeight;
final Duration duration = const Duration(milliseconds: 300);
AnimationController _controller;
Animation<double> _scaleAnimation;
Animation<double> _menuScaleAnimation;
Animation<Offset> _slideAnimation;
Vente vente;
List<Vente> list = List();
List<Produit> produits = List();
Produit produit = Produit();
@override
void initState() {
getVente();
_controller = AnimationController(vsync: this, duration: duration);
_scaleAnimation = Tween<double>(begin: 1, end: 0.8).animate(_controller);
_menuScaleAnimation =
Tween<double>(begin: 0.5, end: 1).animate(_controller);
_slideAnimation = Tween<Offset>(begin: Offset(-1, 0), end: Offset(0, 0))
.animate(_controller);
super.initState();
}
void getVente() async {
bool trouve = false;
await for (var snapshots
in FirebaseFirestore.instance.collection('vente').snapshots()) {
for (var ventes in snapshots.docs) {
if ((ventes['client_id'] != null) && (ventes['date'] != null)) {
if (list.isNotEmpty) {
for (var sells in list) {
if ((sells.clientid == ventes['client_id']) &&
(sells.date == ventes['date'])) {
trouve = true;
produit = Produit();
produit.baseprice = ventes['baseprice'];
produit.couttotale = ventes['couttotale'];
produit.nbarticle = ventes['nb_product'];
produit.prixpromo = ventes['prixpromo'];
produit.nom = ventes['marque'];
sells.produits.add(produit);
sells.montant += produit.couttotale;
}
}
if (!trouve) {
vente = Vente(
clientid: ventes['client_id'],
clientnom: ventes['client_name'],
date: ventes['date'],
data: ventes,
montant: ventes['couttotale'],
);
produit = Produit();
produit.baseprice = ventes['baseprice'];
produit.couttotale = ventes['couttotale'];
produit.nbarticle = ventes['nb_product'];
produit.prixpromo = ventes['prixpromo'];
produit.nom = ventes['marque'];
vente.produits = List<Produit>();
vente.produits.add(produit);
list.add(vente);
}
trouve = false;
} else {
vente = Vente(
clientid: ventes['client_id'],
clientnom: ventes['client_name'],
date: ventes['date'],
data: ventes,
montant: ventes['couttotale'],
);
vente.produits = List<Produit>();
produit = Produit();
produit.baseprice = ventes['baseprice'];
produit.couttotale = ventes['couttotale'];
produit.nbarticle = ventes['nb_product'];
produit.prixpromo = ventes['prixpromo'];
produit.nom = ventes['marque'];
vente.produits.add(produit);
list.add(vente);
}
}
}
}
setState(() {});
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
screenHeight = size.height;
screenWidth = size.width;
return Scaffold(
backgroundColor: backgroundColor,
body: Stack(
children: <Widget>[
menu(context),
dashboard(context),
],
),
);
}
int tag = 0;
List<String> options = [
'Date',
'Client',
'Montant',
];
final elements1 = [
"Alger",
"Harach",
"Beo",
"Said Hamdine",
"Ain Naadja",
"Kouba",
"Garidi",
];
_openPopup(context) {
DateTime mindate, maxdate;
Alert(
context: context,
title: "Filtres",
style: AlertStyle(
backgroundColor: Colors.grey[200],
titleStyle: TextStyle(
fontFamily: 'Mom cake',
fontWeight: FontWeight.bold,
fontSize: 34)),
content: SizedBox(
width: screenWidth,
height: screenHeight * 0.6,
child: Padding(
padding: const EdgeInsets.only(left: 8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text("Trier par :",
style: TextStyle(
fontFamily: 'Mom cake',
fontWeight: FontWeight.bold,
fontSize: 34)),
Row(
children: [
Expanded(
child: ChipsChoice<int>.single(
value: tag,
onChanged: (val) => setState(() => tag = val),
choiceItems: C2Choice.listFrom<int, String>(
source: options,
value: (i, v) => i,
label: (i, v) => v,
),
choiceStyle: C2ChoiceStyle(
color: Colors.black,
borderRadius:
const BorderRadius.all(Radius.circular(10)),
),
),
),
],
),
Text("Secteur :"),
MyStatefulWidget(),
Text("Client : "),
MyStatefulWidget2(),
Text("Montant de vente"),
Row(
children: [
SizedBox(
width: 110.0,
child: TextFormField(
decoration: InputDecoration(
labelText: 'MIN',
border: OutlineInputBorder(),
),
),
),
SizedBox(
width: 8,
child: Divider(
thickness: 2.0,
),
),
SizedBox(
width: 110.0,
child: TextFormField(
decoration: InputDecoration(
labelText: 'MAX',
border: OutlineInputBorder(),
),
),
),
],
),
Text("Date de vente"),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SizedBox(
width: 150.0,
height: 70,
child: IconButton(
icon: Icon(
Icons.date_range_rounded,
),
onPressed: () async {
final List<DateTime> picked =
await DateRagePicker.showDatePicker(
context: context,
initialFirstDate: new DateTime.now(),
initialLastDate: new DateTime.now()
.add(new Duration(days: 7)),
firstDate: new DateTime(2015),
lastDate: new DateTime(2030));
if (picked != null && picked.length == 2) {
mindate = picked[1];
maxdate = picked[2];
}
},
),
),
],
),
],
),
),
),
buttons: [
DialogButton(
onPressed: () => Navigator.pop(context),
child: Text(
"Filtrer",
style: TextStyle(color: Colors.white, fontSize: 17),
),
),
DialogButton(
onPressed: () => Navigator.pop(context),
child: Text(
"Réinitialiser",
style: TextStyle(color: Colors.white, fontSize: 17),
),
)
]).show();
}
Widget menu(context) {
return ... some widget ...
}
Widget dashboard(context) {
return AnimatedPositioned(
duration: duration,
top: 0,
bottom: 0,
left: isCollapsed ? 0 : 0.6 * screenWidth,
right: isCollapsed ? 0 : -0.2 * screenWidth,
child: ScaleTransition(
scale: _scaleAnimation,
child: Material(
animationDuration: duration,
borderRadius: BorderRadius.all(Radius.circular(40)),
elevation: 8,
color: backgroundColor,
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
physics: ClampingScrollPhysics(),
child: Container(
padding: const EdgeInsets.only(left: 16, right: 16, top: 37),
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.max,
children: [
InkWell(
child: Icon(Icons.menu, color: Colors.white),
onTap: () {
setState(() {
if (isCollapsed) {
_controller.forward();
} else
_controller.reverse();
isCollapsed = !isCollapsed;
});
},
),
Text("Historique",
style:
TextStyle(fontSize: 24, color: Colors.white)),
IconButton(
icon: CircleAvatar(
radius: 15.0,
backgroundImage:
AssetImage('assets/images/search.png'),
),
onPressed: () {
_openPopup(context);
setState(() {});
})
],
),
ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: list.length,
itemBuilder: (context, index) {
return HistoryItem(
client_id: list[index].clientid,
date: list[index].date,
clientnom: list[index].clientnom,
screenWidth: MediaQuery.of(context).size.width,
documentSnapshot: list[index].data,
montant: list[index].montant,
produits: list[index].produits,
);
},
),
],
),
),
),
),
),
),
);
}
}
class Vente {
DocumentSnapshot data;
String clientid;
String clientnom;
String date;
double montant;
List<Produit> produits;
Vente(
{@required this.clientid,
this.date,
this.data,
this.clientnom,
this.produits,
this.montant});
}
class Produit {
String nom;
int baseprice;
double prixpromo;
double couttotale;
int nbarticle;
Produit(
{this.baseprice,
this.nbarticle,
this.nom,
this.couttotale,
this.prixpromo});
}

您可以使用FutureBuilder小部件。用FutureBuilder包装您的ListView.builder

FutureBuilder<List<Vente>(
future: getVente(),
builder: (context, stream){
if(stream.hasData){
return ListView.builder();
} else {
return CircularProgressIndicator() ;
}
}
)

更新您的getVente((方法

Future<List<Vente>> getVente() async {
bool trouve = false;
await for (QuerySnapshot snapshots
in FirebaseFirestore.instance.collection('vente').snapshots()) {
for (var ventes in snapshots.docs) {
if ((ventes['client_id'] != null) && (ventes['date'] != null)) {
if (list.isNotEmpty) {
for (var sells in list) {
if ((sells.clientid == ventes['client_id']) &&
(sells.date == ventes['date'])) {
trouve = true;
produit = Produit();
produit.baseprice = ventes['baseprice'];
produit.couttotale = ventes['couttotale'];
produit.nbarticle = ventes['nb_product'];
produit.prixpromo = ventes['prixpromo'];
produit.nom = ventes['marque'];
sells.produits.add(produit);
sells.montant += produit.couttotale;
}
}
if (!trouve) {
vente = Vente(
clientid: ventes['client_id'],
clientnom: ventes['client_name'],
date: ventes['date'],
data: ventes,
montant: ventes['couttotale'],
);
produit = Produit();
produit.baseprice = ventes['baseprice'];
produit.couttotale = ventes['couttotale'];
produit.nbarticle = ventes['nb_product'];
produit.prixpromo = ventes['prixpromo'];
produit.nom = ventes['marque'];
vente.produits = List<Produit>();
vente.produits.add(produit);
list.add(vente);
}
trouve = false;
} else {
vente = Vente(
clientid: ventes['client_id'],
clientnom: ventes['client_name'],
date: ventes['date'],
data: ventes,
montant: ventes['couttotale'],
);
vente.produits = List<Produit>();
produit = Produit();
produit.baseprice = ventes['baseprice'];
produit.couttotale = ventes['couttotale'];
produit.nbarticle = ventes['nb_product'];
produit.prixpromo = ventes['prixpromo'];
produit.nom = ventes['marque'];
vente.produits.add(produit);
list.add(vente);
}
}
}
}
return list; // Add this here
}

解释

FutureBuilder<T>将等待未来的完成。

在这种情况下,FutureBuilder<void>不需要任何东西,就像返回void的方法getVente()一样。它将等待代码完成,并通知生成器。在这种情况下,您不需要在initState中调用getVente()方法,因为FutureBuilder将为您执行此操作。

您也可以使用更好的FutureBuilder<List<Vente>>,但您需要对代码进行大量更改。它需要一个Vente对象的列表,您可以在生成器方法中使用它。

future.connectionState == ConnectionState.waiting将检查未来是否仍在连接中,并且尚未完成。在这种情况下,构建器将显示CircularProgressIndicator()

当future完成时,它将返回ListView.builder方法。

如果你愿意,你可以找到更多关于FutureBuilder的信息。

如果希望在值更改时更新小部件,也可以使用StreamBuilder

StreamBuilder<List<Vente>(
stream: getVente(),
builder: (context, future){
if(future.hasData){
return ListView.builder();
} else {
return CircularProgressIndicator() ;
}
}
)

更新您的getVente((方法

Stream<List<Vente>> getVente() async* {
bool trouve = false;
await for (QuerySnapshot snapshots
in FirebaseFirestore.instance.collection('vente').snapshots()) {
for (var ventes in snapshots.docs) {
if ((ventes['client_id'] != null) && (ventes['date'] != null)) {
if (list.isNotEmpty) {
for (var sells in list) {
if ((sells.clientid == ventes['client_id']) &&
(sells.date == ventes['date'])) {
trouve = true;
produit = Produit();
produit.baseprice = ventes['baseprice'];
produit.couttotale = ventes['couttotale'];
produit.nbarticle = ventes['nb_product'];
produit.prixpromo = ventes['prixpromo'];
produit.nom = ventes['marque'];
sells.produits.add(produit);
sells.montant += produit.couttotale;
}
}
if (!trouve) {
vente = Vente(
clientid: ventes['client_id'],
clientnom: ventes['client_name'],
date: ventes['date'],
data: ventes,
montant: ventes['couttotale'],
);
produit = Produit();
produit.baseprice = ventes['baseprice'];
produit.couttotale = ventes['couttotale'];
produit.nbarticle = ventes['nb_product'];
produit.prixpromo = ventes['prixpromo'];
produit.nom = ventes['marque'];
vente.produits = List<Produit>();
vente.produits.add(produit);
list.add(vente);
}
trouve = false;
} else {
vente = Vente(
clientid: ventes['client_id'],
clientnom: ventes['client_name'],
date: ventes['date'],
data: ventes,
montant: ventes['couttotale'],
);
vente.produits = List<Produit>();
produit = Produit();
produit.baseprice = ventes['baseprice'];
produit.couttotale = ventes['couttotale'];
produit.nbarticle = ventes['nb_product'];
produit.prixpromo = ventes['prixpromo'];
produit.nom = ventes['marque'];
vente.produits.add(produit);
list.add(vente);
}
}
}
}
yield list; // Add this here
}

最新更新