【发布时间】:2021-03-05 20:55:42
【问题描述】:
我正在开发一个小型待办事项列表应用程序,我是 Provider 包的新手。我收到此错误:
错误:在此上方找不到正确的提供程序 生成器小部件。发生这种情况是因为您使用了“BuildContext” 不包括您选择的提供商。
When the exception was thrown, this was the stack:
#0 Provider._inheritedElementOf (package:provider/src/provider.dart:332:7)
#1 Provider.of (package:provider/src/provider.dart:284:30)
#2 HomePage.build.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:mytodolist/main.dart:57:36)
#3 _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:994:20)
#4 GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:182:24)
...
Handler: "onTap"
Recognizer: TapGestureRecognizer#9540a
debugOwner: GestureDetector
state: possible
won arena
finalPosition: Offset(308.6, 425.5)
finalLocalPosition: Offset(34.8, 20.3)
button: 1
sent tap down
这是我的main.dart:
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:mytodolist/TodoModel.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
brightness: Brightness.light,
primaryColor: Colors.blue,
accentColor: Colors.orange,
),
home: ChangeNotifierProvider(
create: (context) => TodoModel(),
child: HomePage(),
)
);
}
}
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("mytodos"),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8)),
title: Text("Add Todolist"),
content: TextField(
onChanged: (String value) {
Provider.of<TodoModel>(context, listen: false)
.addTitle(value);
},
),
actions: <Widget>[
TextButton(
onPressed: () {
Provider.of<TodoModel>(context, listen: false)
.createTodos();
Navigator.of(context).pop();
},
child: Text("Add"))
],
);
});
},
child: Icon(
Icons.add,
color: Colors.white,
),
),
body: StreamBuilder(
stream: FirebaseFirestore.instance.collection("MyTodos").snapshots(),
builder: (context, snapshots) {
if (snapshots.data == null) return CircularProgressIndicator();
return Consumer<TodoModel>(builder: (context, todo, child) {
return ListView.builder(
shrinkWrap: true,
itemCount: snapshots.data.docs.length,
itemBuilder: (context, index) {
DocumentSnapshot documentSnapshot =
snapshots.data.docs[index];
return Dismissible(
onDismissed: (direction) {
Provider.of<TodoModel>(context, listen: false)
.deleteTodos(documentSnapshot["todoTitle"]);
},
key: Key(documentSnapshot["todoTitle"]),
child: Card(
elevation: 4,
margin: EdgeInsets.all(8),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8)),
child: ListTile(
title: Text(documentSnapshot["todoTitle"]),
trailing: IconButton(
icon: Icon(Icons.delete),
color: Colors.red,
onPressed: () {
/*setState(() {
todos.removeAt(index);
});*/
Provider.of<TodoModel>(context, listen: false)
.deleteTodos(documentSnapshot["todoTitle"]);
},
),
),
));
});
});
}),
);
}
}
这是我的 TodoModel.dart:
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/cupertino.dart';
class TodoModel extends ChangeNotifier {
// List todos = [];
String todoTitle = "";
createTodos() {
DocumentReference documentReference =
FirebaseFirestore.instance.collection("MyTodos").doc(todoTitle);
// Map
Map<String, String> todos = {"todoTitle": todoTitle};
documentReference.set(todos).whenComplete(() =>
print("$todoTitle created"));
}
deleteTodos(item) {
DocumentReference documentReference =
FirebaseFirestore.instance.collection("MyTodos").doc(item);
documentReference.delete().whenComplete(() => print("$item deleted"));
}
addTitle(String title) {
todoTitle = title;
}
}
在main.dart 中,我相信我已经将ChangeNotifierProvider 提升到足以使其子HomePage 类使用Provider.of<TodoModel>(content).xxx。为什么Builder Widget上方还是会弹出找不到正确Provider的错误?
【问题讨论】:
-
按
FloatingActionButton时是否出现错误? -
@rickimaru 不是。它在按下按钮后发生,当我在
AlertDialog中输入文本时弹出 -
啊,你是对的,我看错了你的代码。请使用
HomePage的context,而不是showDialog(..., builder: (BuildContext doNotUseThisToGetTheProvider) {...}。 -
@rickimaru 非常感谢您的跟进!您能否说得更具体一点(因为我对 Flutter 完全陌生,哈哈)?我不确定如何在
showDialog中使用HomePage的context。 -
请参考我下面的回答。请参阅带有
<<<<<<<cmets 的行。
标签: flutter dart flutter-provider