列表视图在流完成检索数据之前引发错误
Posted
技术标签:
【中文标题】列表视图在流完成检索数据之前引发错误【英文标题】:List view throws an error before stream has finished retrieving data 【发布时间】:2020-07-13 20:13:10 【问题描述】:我一直在学习Flutter
并关注关于Provider
包的在线教程,目前我正在使用StreamProvider
。
我有一个服务可以连接到Firestore
并返回集合中的所有文档(“报告”),然后将这些文档映射到我的报告对象。
服务:
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 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 方法完成之前构建列表视图?处理此类任务的最佳方法是什么?
谢谢
【问题讨论】:
【参考方案1】:试试这个:
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();
,
),
);
【讨论】:
我已经添加了它并且它有效,谢谢,只是想知道是否有更优雅的方式通知用户 1)我们正在获取数据 2)我们已经收到数据所以显示它,或者如果我们没有数据,则显示“找不到数据” 我已经编辑了我的答案并添加了一个条件。首先它会检查报告是否为空。如果它为空,则表示它当前正在获取报告,因此我们将显示正在获取报告的消息。之后获取报告并且报告不为空,我们将检查报告的长度是否大于 0。如果更大,我们将显示报告,否则我们将显示没有数据的消息。 会试一试,我确实在您提供的代码 sn-p 末尾收到错误,认为它缺少冒号不确定,仍在查看它 道歉。这是一个语法错误。我已经更新了我的答案。 非常感谢您的修复。 listivew 现在不再显示。不知道为什么。以上是关于列表视图在流完成检索数据之前引发错误的主要内容,如果未能解决你的问题,请参考以下文章