仅在热重载后检索数据
Data is retrieved only after hot reloading
我是 Flutter 的新手,我正在尝试从 Firebase 实时数据库中检索数据。但是,只有在执行热重载时才会检索来自 firebase 的数据。我不知道该怎么办...这是代码:
import 'package:firebase_database/firebase_database.dart';
import 'package:flutter/material.dart';
import 'Posts.dart';
class HomePage extends StatefulWidget{
@override
State<StatefulWidget> createState() {
return HomePageState();
}
}
class HomePageState extends State<HomePage>{
List <Posts> postsList = [];
void initState() {
super.initState();
_fetchList();
}
_fetchList() async {
DatabaseReference postsRef = FirebaseDatabase.instance.reference().child("Posts");
postsRef.once().then((DataSnapshot snap){
// ignore: non_constant_identifier_names
var KEYS = snap.value.keys;
var DATA = snap.value;
for(var individualKey in KEYS){
Posts posts = Posts(
DATA[individualKey]["date"],
DATA[individualKey]["description"],
DATA[individualKey]["time"],
);
postsList.add(posts);
}
} );}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: Text(
"Home",
)
),
body: Container(
child: postsList.length==0? Text("Nothing available!") : ListView.builder(
itemCount: postsList.length,
itemBuilder:(context,int index){
return postsUI(postsList[index].description, postsList[index].date, postsList[index].time);
}
),
));
}
Widget postsUI ( String description, String date, String time){
return Card(
elevation: 20.0,
margin: EdgeInsets.only(left: 25.0 , right:25.0, top:15.0, bottom:15.0),
child: Container(
padding: EdgeInsets.all(20.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children:<Widget> [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
date,
style: Theme.of(context).textTheme.subtitle1,
textAlign: TextAlign.center,
),
Text(
time,
style: Theme.of(context).textTheme.subtitle1,
textAlign: TextAlign.center,
),
],
),
SizedBox(height: 15.0,),
Text(
description,
style: Theme.of(context).textTheme.subtitle2,
textAlign: TextAlign.center,
),
],
),
),
);
}
}
PS :仅在执行热重载时从数据库中检索值。
我假设您要检索的数据来自 _fetchList()
调用?它只在热重载中工作的原因是因为你只有 _fetchList
从 initState
调用——它只在 运行.
上调用
如果您希望获得 real-time 更新(当数据库中的内容发生变化时您的小部件会更新),您需要考虑使用 Streams and StreamBuilder.
如果您希望使用 fetchData
Firestore 数据构建 UI 而无需 real-time 更新,Futures and FutureBuilder 就是您想要的。从您的代码来看,我认为这将满足您的需求。
除了 J.Saw 的出色回答,您还可以选择将 postsList
存储在小部件的状态中。
为此,您在数据加载后调用 setState()
:
_fetchList() async {
DatabaseReference postsRef = FirebaseDatabase.instance.reference().child("Posts");
postsRef.once().then((DataSnapshot snap){
// ignore: non_constant_identifier_names
var KEYS = snap.value.keys;
var DATA = snap.value;
for(var individualKey in KEYS){
Posts posts = Posts(
DATA[individualKey]["date"],
DATA[individualKey]["description"],
DATA[individualKey]["time"],
);
postsList.add(posts);
}
setState((){
this.postsList = postsList;
});
});
}
调用 setState()
会导致 Flutter 重新绘制小部件,然后它可以像您已经在做的那样访问数据。
您也许可以不带任何参数地简单地调用 setState(() {})
,但我总是更喜欢传入修改后的状态 - 即使不需要它。
我是 Flutter 的新手,我正在尝试从 Firebase 实时数据库中检索数据。但是,只有在执行热重载时才会检索来自 firebase 的数据。我不知道该怎么办...这是代码:
import 'package:firebase_database/firebase_database.dart';
import 'package:flutter/material.dart';
import 'Posts.dart';
class HomePage extends StatefulWidget{
@override
State<StatefulWidget> createState() {
return HomePageState();
}
}
class HomePageState extends State<HomePage>{
List <Posts> postsList = [];
void initState() {
super.initState();
_fetchList();
}
_fetchList() async {
DatabaseReference postsRef = FirebaseDatabase.instance.reference().child("Posts");
postsRef.once().then((DataSnapshot snap){
// ignore: non_constant_identifier_names
var KEYS = snap.value.keys;
var DATA = snap.value;
for(var individualKey in KEYS){
Posts posts = Posts(
DATA[individualKey]["date"],
DATA[individualKey]["description"],
DATA[individualKey]["time"],
);
postsList.add(posts);
}
} );}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: Text(
"Home",
)
),
body: Container(
child: postsList.length==0? Text("Nothing available!") : ListView.builder(
itemCount: postsList.length,
itemBuilder:(context,int index){
return postsUI(postsList[index].description, postsList[index].date, postsList[index].time);
}
),
));
}
Widget postsUI ( String description, String date, String time){
return Card(
elevation: 20.0,
margin: EdgeInsets.only(left: 25.0 , right:25.0, top:15.0, bottom:15.0),
child: Container(
padding: EdgeInsets.all(20.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children:<Widget> [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
date,
style: Theme.of(context).textTheme.subtitle1,
textAlign: TextAlign.center,
),
Text(
time,
style: Theme.of(context).textTheme.subtitle1,
textAlign: TextAlign.center,
),
],
),
SizedBox(height: 15.0,),
Text(
description,
style: Theme.of(context).textTheme.subtitle2,
textAlign: TextAlign.center,
),
],
),
),
);
}
}
PS :仅在执行热重载时从数据库中检索值。
我假设您要检索的数据来自 _fetchList()
调用?它只在热重载中工作的原因是因为你只有 _fetchList
从 initState
调用——它只在 运行.
如果您希望获得 real-time 更新(当数据库中的内容发生变化时您的小部件会更新),您需要考虑使用 Streams and StreamBuilder.
如果您希望使用 fetchData
Firestore 数据构建 UI 而无需 real-time 更新,Futures and FutureBuilder 就是您想要的。从您的代码来看,我认为这将满足您的需求。
除了 J.Saw 的出色回答,您还可以选择将 postsList
存储在小部件的状态中。
为此,您在数据加载后调用 setState()
:
_fetchList() async {
DatabaseReference postsRef = FirebaseDatabase.instance.reference().child("Posts");
postsRef.once().then((DataSnapshot snap){
// ignore: non_constant_identifier_names
var KEYS = snap.value.keys;
var DATA = snap.value;
for(var individualKey in KEYS){
Posts posts = Posts(
DATA[individualKey]["date"],
DATA[individualKey]["description"],
DATA[individualKey]["time"],
);
postsList.add(posts);
}
setState((){
this.postsList = postsList;
});
});
}
调用 setState()
会导致 Flutter 重新绘制小部件,然后它可以像您已经在做的那样访问数据。
您也许可以不带任何参数地简单地调用 setState(() {})
,但我总是更喜欢传入修改后的状态 - 即使不需要它。