【发布时间】:2020-09-15 16:05:03
【问题描述】:
我正在尝试将 StreamBuilder 与 ListView.builder 结合使用来显示存储在 firebase 上的数组中的数据。
我尝试使用下面的代码访问数组,但我真的不知道我做错了什么。
class Home extends StatelessWidget {
@override
Widget build(BuildContext context) {
return StreamBuilder<List<Beacon>>(
stream: DatabaseService().beacons,
builder: (context, snapshot) {
return BeaconList(),
}
);
}
}
class BeaconList extends StatefulWidget {
@override
_BeaconListState createState() => _BeaconListState();
}
class _BeaconListState extends State<BeaconList> {
@override
Widget build(BuildContext context) {
final beacons = Provider.of<List<Beacon>>(context) ?? [];
return ListView.builder(
itemCount: beacons.length,
itemBuilder: (context, index) {
return BeaconTile(beacon: beacons[index]);
},
);
}
}
class BeaconTile extends StatefulWidget {
final Beacon beacon;
BeaconTile({this.beacon});
@override
_BeaconTileState createState() => _BeaconTileState();
}
class _BeaconTileState extends State<BeaconTile> {
@override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.only(top: 8),
child: Card(
margin: EdgeInsets.fromLTRB(20, 6, 20, 0),
child: ListTile(
leading: CircleAvatar(
radius: 25,
backgroundColor: widget.beacon.bid Colors.green[400],
),
title: Text("Connection made"),
subtitle: Text("ID: ${widget.beacon.bid}"),
),
),
);
}
}
class Beacon {
String bid;
Beacon({this.bid});
}
final DocumentReference beaconCollection = Firestore.instance.collection("LocationData").document("BeaconData");
List<Beacon> _beaconListFromSnapshot(DocumentSnapshot snapshot) {
List<Beacon> beaconList = [];
for (int i = 0; i < snapshot.data.length; i++) {
print(i);
beaconList.add(Beacon(bid: snapshot.data[i]));
}
return beaconList;
}
Stream<List<Beacon>> get beacons {
return beaconCollection.get()
.then((snapshot) {
try {
return _beaconListFromSnapshot(snapshot);
} catch(e) {
print(e.toString());
return null;
}
}).asStream();
}
运行上面的代码我得到了错误:
I/flutter (30206): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
I/flutter (30206): The following ProviderNotFoundException was thrown building BeaconList(dirty, state:
I/flutter (30206): _BeaconListState#6361b):
I/flutter (30206): Error: Could not find the correct Provider<List<Beacon>> above this BeaconList Widget
I/flutter (30206):
I/flutter (30206): This likely happens because you used a `BuildContext` that does not include the provider
I/flutter (30206): of your choice. There are a few common scenarios:
I/flutter (30206):
I/flutter (30206): - The provider you are trying to read is in a different route.
I/flutter (30206):
I/flutter (30206): Providers are "scoped". So if you insert of provider inside a route, then
I/flutter (30206): other routes will not be able to access that provider.
I/flutter (30206):
I/flutter (30206): - You used a `BuildContext` that is an ancestor of the provider you are trying to read.
I/flutter (30206):
I/flutter (30206): Make sure that BeaconList is under your MultiProvider/Provider<List<Beacon>>.
I/flutter (30206): This usually happen when you are creating a provider and trying to read it immediately.
I/flutter (30206):
I/flutter (30206): For example, instead of:
I/flutter (30206):
I/flutter (30206): ```
I/flutter (30206): Widget build(BuildContext context) {
I/flutter (30206): return Provider<Example>(
I/flutter (30206): create: (_) => Example(),
I/flutter (30206): // Will throw a ProviderNotFoundError, because `context` is associated
I/flutter (30206): // to the widget that is the parent of `Provider<Example>`
I/flutter (30206): child: Text(context.watch<Example>()),
I/flutter (30206): ),
I/flutter (30206): }
I/flutter (30206): ```
I/flutter (30206):
I/flutter (30206): consider using `builder` like so:
I/flutter (30206):
I/flutter (30206): ```
I/flutter (30206): Widget build(BuildContext context) {
I/flutter (30206): return Provider<Example>(
I/flutter (30206): create: (_) => Example(),
I/flutter (30206): // we use `builder` to obtain a new `BuildContext` that has access to the provider
I/flutter (30206): builder: (context) {
I/flutter (30206): // No longer throws
I/flutter (30206): return Text(context.watch<Example>()),
I/flutter (30206): }
I/flutter (30206): ),
I/flutter (30206): }
I/flutter (30206): ```
I/flutter (30206):
I/flutter (30206): If none of these solutions work, consider asking for help on StackOverflow:
I/flutter (30206): https://stackoverflow.com/questions/tagged/flutter
I/flutter (30206):
I/flutter (30206): The relevant error-causing widget was:
I/flutter (30206): BeaconList file:///F:/apps/rivi_mvp/lib/screens/home/home.dart:43:19
I/flutter (30206):
我尝试了很多不同的方法,但我认为我对 StreamBuilders 和 Providers 和流的了解不足以找到解决方案。任何解决方案或见解将不胜感激。
【问题讨论】:
-
你为什么使用提供者?
标签: firebase flutter google-cloud-firestore