【发布时间】:2020-11-28 07:46:55
【问题描述】:
这是我在 MultiProvider 中使用 StreamProvider 的主文件。我的提供者正在包装 MaterialApp,以便之后的其他小部件可以访问我的建筑物列表。
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
final FirestoreService _db = FirestoreService();
return MultiProvider(
providers: [
StreamProvider(
create: (BuildContext context) => _db.getBuildings(),
)
],
child: MaterialApp(
theme: ThemeData.light().copyWith(
primaryColor: Hexcolor(kUntGreen),
),
home: NavigationDrawer(
title: 'Campus Explorer',
),
),
);
}
在我的 NavigationDrawer 中,我使用 switch 语句呈现所选页面
class _NavigationDrawerState extends State<NavigationDrawer> {
int _selectedItem = 0;
Widget _getPage(selectedIndex) {
switch (selectedIndex) {
case 0:
return MyPoints();
case 1:
return AllBuildings();
case 2:
return UNTApplications();
default:
return new Text("Error");
}
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
drawer: Drawer(...),
body: _getPage(_selectedItem),
),
);
}
}
当我尝试在以下代码中使用我的提供程序访问我的列表时:
class AllBuildings extends StatelessWidget {
@override
Widget build(BuildContext context) {
var buildings = Provider.of<List<Building>>(context);
return Scaffold(
body: ListView.builder(
itemCount: buildings.length,
itemBuilder: (context, i) {
var building = buildings[i];
return ListTile(
leading: Text(building.buildingName),
title: Text(building.buildingId),
);
},
),
);
}
}
我收到以下错误:
════════ Exception caught by widgets library ═══════════════════════════════════════════════════════
The following ProviderNotFoundException was thrown building AllBuildings(dirty):
Error: Could not find the correct Provider<List<Building>> above this AllBuildings Widget
This likely happens because you used a `BuildContext` that does not include the provider
of your choice. There are a few common scenarios:
- The provider you are trying to read is in a different route.
Providers are "scoped". So if you insert of provider inside a route, then
other routes will not be able to access that provider.
- You used a `BuildContext` that is an ancestor of the provider you are trying to read.
Make sure that AllBuildings is under your MultiProvider/Provider<List<Building>>.
This usually happen when you are creating a provider and trying to read it immediatly.
For example, instead of:
Widget build(BuildContext context) {
return Provider<Example>(
create: (_) => Example(),
// Will throw a ProviderNotFoundError, because `context` is associated
// to the widget that is the parent of `Provider<Example>`
child: Text(context.watch<Example>()),
),
}
consider using `builder` like so:
Widget build(BuildContext context) {
return Provider<Example>(
create: (_) => Example(),
// we use `builder` to obtain a new `BuildContext` that has access to the provider
builder: (context) {
// No longer throws
return Text(context.watch<Example>()),
}
),
}
If none of these solutions work, consider asking for help on StackOverflow:
https://stackoverflow.com/questions/tagged/flutter
The relevant error-causing widget was:
AllBuildings file:///C:/Users/HP/Desktop/Flutter/campus_explorer/lib/navigation/navigation_drawer.dart:27:16
When the exception was thrown, this was the stack:
#0 Provider._inheritedElementOf (package:provider/src/provider.dart:269:7)
#1 Provider.of (package:provider/src/provider.dart:221:30)
#2 AllBuildings.build (package:campus_explorer/pages/all_buildings.dart:8:30)
#3 StatelessElement.build (package:flutter/src/widgets/framework.dart:4620:28)
#4 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4546:15)
我尝试不使用导航抽屉,而是使用 push 将页面推送到堆栈上。 我还尝试在没有 MultiProvider 的情况下直接使用 streamProvider。我试过的都没有用
这是我获取建筑物的 FirestoreService。我还有另一个函数是 addBuilding(),但我现在没有使用它。
class FirestoreService {
Firestore _db = Firestore.instance;
Stream<List<Building>> getBuildings() {
return _db
.collection('buildings')
.orderBy('building_name', descending: false)
.snapshots()
.map((snapshot) => snapshot.documents
.map((document) => Building.fromJson(document.data))
.toList());
}
Future<void> addBuilding() {
var dataMap = Map<String, dynamic>();
return _db.collection('buildings').add(dataMap);
}
}
【问题讨论】:
-
你的 getBuildings 函数返回什么?
-
它返回 Stream
- >。这是函数:
Stream<List<Building>> getBuildings() -
我不认为这是问题所在,但至少在构建函数中使用
final FirestoreService _db = FirestoreService();可能不是一个好主意。最好放在外面。虽然这可能没问题,这取决于 Firestore 内部的工作方式。 -
我只是尝试取出并没有改变任何东西。我仍然遇到同样的错误。
-
考虑输入
StreamProvider<List<Building>>以确保。