这是我在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中,我使用切换语句呈现所选页面
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)
我试着不使用导航抽屉,而是使用推送来推送堆栈上的页面。我还尝试在没有MultiProvider的情况下直接使用streamProvider。我尝试过的任何东西都无效
这是我的消防服务,我在那里得到建筑。我有另一个函数addBuild((,但我现在没有使用它。
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);
}
}
试试这个:
Stream<List<Building>> getBuildings() {
return _db
.collection('buildings')
.orderBy('building_name', descending: false)
.snapshots()
.map((query) => query.documents)
.map((snapshot) => snapshot
.map((document) => Building.fromJson(document.data))
.toList());
}
我终于发现我的代码有什么问题。我的进口声明中多了一个正斜杠。
import 'package:campus_explorer/models//building.dart';
取而代之的是:
import 'package:campus_explorer/models/building.dart';
我不确定为什么这会引起这样的问题,但我认为它指的是错误的类型。