列表视图在流完成检索数据之前抛出错误
List view throws an error before stream has finished retrieving data
我一直在学习 Flutter
并遵循有关 Provider
包的在线教程,目前我正在使用 StreamProvider
。
我有一个服务连接到 Firestore
和 returns 集合中的所有文档 ('reports'),然后将这些文档映射到我的报告对象。
服务:
class FirestoreService {
Firestore _db = Firestore.instance;
var random = Random();
Stream<List<Report>> getReports() {
return _db.collection('reports')
.orderBy('timeStamp', descending: true)
.snapshots()
.map((snapshot) => snapshot.documents
.map((document) => Report.fromJson(document.data))
.toList());
}
举报class:
class Report {
final int temp;
final String wax;
final String line;
final String timeStamp;
Report({this.line,this.temp,this.timeStamp,this.wax});
Report.fromJson(Map<String, dynamic> parsedJson)
: temp = parsedJson['temp'],
wax = parsedJson['wax'],
line = parsedJson['line'],
timeStamp = parsedJson['timeStamp'];
}
在 main.dart
中,我使用了 MultiProvider
并添加了我的 StreamProvider
。
main.dart:
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
final FirestoreService _db = FirestoreService();
return MultiProvider(
providers: [
ChangeNotifierProvider(create: (BuildContext context) => SettingsProvider()),
StreamProvider(create: (BuildContext context) => _db.getReports(),)
],
child: MaterialApp(
title: 'Wax App',
theme: ThemeData(
primarySwatch: Colors.deepPurple,
accentColor: Colors.deepOrangeAccent),
home: Home(),
),
);
}}
现在是问题所在,在 home.dart
中,我检索了报告数据并构建了一个列表视图,但是在 getReports
方法完成之前调用了列表视图,偶尔会抛出错误引用 var reports
home.dart:
class Home extends StatelessWidget {
@override
Widget build(BuildContext context) {
var reports = Provider.of<List<Report>>(context);
FirestoreService _db = FirestoreService();
return Scaffold(
appBar: AppBar(
title: Text('Wax App'),
centerTitle: true,
actions: <Widget>[
IconButton(
icon: Icon(Icons.settings),
onPressed: () {
Navigator.of(context)
.push(MaterialPageRoute(builder: (context) => Settings()));
})
],
),
body: ListView.builder(
itemCount: reports.length,
itemBuilder: (context, index) {
Report report = reports[index];
return ListTile(
leading: Text(report.temp.toString()),
title: Text(report.wax),
subtitle: Text(report.line),
trailing: Text(formatDate(DateTime.parse(report.timeStamp), [h, ':', mm, ' ', am])));
}
) ,
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () {
_db.addReport();
},
),
);
}}
例如,这一行会抛出一个错误:
itemCount: reports.length
此时报告为空,所以我的问题是如何防止在 getReports 方法完成之前构建列表视图?处理此类任务的最佳方法是什么?
谢谢
试试这个:
class Home extends StatelessWidget {
@override
Widget build(BuildContext context) {
var reports = Provider.of<List<Report>>(context);
FirestoreService _db = FirestoreService();
return Scaffold(
appBar: AppBar(
title: Text('Wax App'),
centerTitle: true,
actions: <Widget>[
IconButton(
icon: Icon(Icons.settings),
onPressed: () {
Navigator.of(context)
.push(MaterialPageRoute(builder: (context) => Settings()));
})
],
),
body: reports!=null ? (reports.length > 0 ? ListView.builder(
itemCount: reports.length,
itemBuilder: (context, index) {
Report report = reports[index];
return ListTile(
leading: Text(report.temp.toString()),
title: Text(report.wax),
subtitle: Text(report.line),
trailing: Text(formatDate(DateTime.parse(report.timeStamp), [h, ':', mm, ' ', am])));
}
): Center(child: Text("We have received no data"))) : Center(child: Text("We are fetching data.Please wait...")),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () {
_db.addReport();
},
),
);
}}
我一直在学习 Flutter
并遵循有关 Provider
包的在线教程,目前我正在使用 StreamProvider
。
我有一个服务连接到 Firestore
和 returns 集合中的所有文档 ('reports'),然后将这些文档映射到我的报告对象。
服务:
class FirestoreService {
Firestore _db = Firestore.instance;
var random = Random();
Stream<List<Report>> getReports() {
return _db.collection('reports')
.orderBy('timeStamp', descending: true)
.snapshots()
.map((snapshot) => snapshot.documents
.map((document) => Report.fromJson(document.data))
.toList());
}
举报class:
class Report {
final int temp;
final String wax;
final String line;
final String timeStamp;
Report({this.line,this.temp,this.timeStamp,this.wax});
Report.fromJson(Map<String, dynamic> parsedJson)
: temp = parsedJson['temp'],
wax = parsedJson['wax'],
line = parsedJson['line'],
timeStamp = parsedJson['timeStamp'];
}
在 main.dart
中,我使用了 MultiProvider
并添加了我的 StreamProvider
。
main.dart:
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
final FirestoreService _db = FirestoreService();
return MultiProvider(
providers: [
ChangeNotifierProvider(create: (BuildContext context) => SettingsProvider()),
StreamProvider(create: (BuildContext context) => _db.getReports(),)
],
child: MaterialApp(
title: 'Wax App',
theme: ThemeData(
primarySwatch: Colors.deepPurple,
accentColor: Colors.deepOrangeAccent),
home: Home(),
),
);
}}
现在是问题所在,在 home.dart
中,我检索了报告数据并构建了一个列表视图,但是在 getReports
方法完成之前调用了列表视图,偶尔会抛出错误引用 var reports
home.dart:
class Home extends StatelessWidget {
@override
Widget build(BuildContext context) {
var reports = Provider.of<List<Report>>(context);
FirestoreService _db = FirestoreService();
return Scaffold(
appBar: AppBar(
title: Text('Wax App'),
centerTitle: true,
actions: <Widget>[
IconButton(
icon: Icon(Icons.settings),
onPressed: () {
Navigator.of(context)
.push(MaterialPageRoute(builder: (context) => Settings()));
})
],
),
body: ListView.builder(
itemCount: reports.length,
itemBuilder: (context, index) {
Report report = reports[index];
return ListTile(
leading: Text(report.temp.toString()),
title: Text(report.wax),
subtitle: Text(report.line),
trailing: Text(formatDate(DateTime.parse(report.timeStamp), [h, ':', mm, ' ', am])));
}
) ,
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () {
_db.addReport();
},
),
);
}}
例如,这一行会抛出一个错误:
itemCount: reports.length
此时报告为空,所以我的问题是如何防止在 getReports 方法完成之前构建列表视图?处理此类任务的最佳方法是什么?
谢谢
试试这个:
class Home extends StatelessWidget {
@override
Widget build(BuildContext context) {
var reports = Provider.of<List<Report>>(context);
FirestoreService _db = FirestoreService();
return Scaffold(
appBar: AppBar(
title: Text('Wax App'),
centerTitle: true,
actions: <Widget>[
IconButton(
icon: Icon(Icons.settings),
onPressed: () {
Navigator.of(context)
.push(MaterialPageRoute(builder: (context) => Settings()));
})
],
),
body: reports!=null ? (reports.length > 0 ? ListView.builder(
itemCount: reports.length,
itemBuilder: (context, index) {
Report report = reports[index];
return ListTile(
leading: Text(report.temp.toString()),
title: Text(report.wax),
subtitle: Text(report.line),
trailing: Text(formatDate(DateTime.parse(report.timeStamp), [h, ':', mm, ' ', am])));
}
): Center(child: Text("We have received no data"))) : Center(child: Text("We are fetching data.Please wait...")),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () {
_db.addReport();
},
),
);
}}