Error: Could not find the correct Provider<NewUser> above this UpdateSupervisor Widget
Error: Could not find the correct Provider<NewUser> above this UpdateSupervisor Widget
如何将流提供者包装在 onPressed 函数中?这是我的 class.
更新主管class
import 'package:finalyearproject/model/NewUser.dart';
import 'package:finalyearproject/service/database.dart';
import 'package:finalyearproject/shared/Loading.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class UpdateSupervisor extends StatefulWidget {
@override
_UpdateSupervisorState createState() => _UpdateSupervisorState();
}
class _UpdateSupervisorState extends State<UpdateSupervisor> {
// form values
String name;
String email;
String uniqueID;
String phone;
String id;
final GlobalKey<FormState> _formKey = GlobalKey();
@override
Widget build(BuildContext context) {
final user = Provider.of<NewUser>(context);
return Scaffold(
appBar: AppBar(
title: Text('Edit Supervisor'),
backgroundColor: Colors.redAccent,
),
body: StreamBuilder(
stream: DatabaseService(uid: user.id).userData,
builder: (context, snapshot){
if(!snapshot.hasData){
return Loading();
}
NewUser userData = snapshot.data;
return Form(
key: _formKey,
child: SingleChildScrollView(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
SizedBox(height: 25.0),
TextFormField(
decoration: InputDecoration(
hintText: 'Name',
border: OutlineInputBorder(borderRadius: BorderRadius.circular(5))),
keyboardType: TextInputType.text,
initialValue: userData.name,
validator: (value) => value.isEmpty ? 'Name cannot be empty!': null,
onChanged: (value) {
setState(() => name = value);
},
),
SizedBox(height: 10.0),
TextFormField(
decoration: InputDecoration(
hintText: 'Email',
border: OutlineInputBorder(borderRadius: BorderRadius.circular(5))),
keyboardType: TextInputType.emailAddress,
validator: (value) => value.isEmpty ? 'Email cannot be empty!': null,
onChanged: (value) {
setState(() => email = value);
},
),
SizedBox(height: 10.0),
TextFormField(
decoration: InputDecoration(
hintText: 'Number Phone',
border: OutlineInputBorder(borderRadius: BorderRadius.circular(5))),
keyboardType: TextInputType.number,
validator: (value) => value.isEmpty ? 'Number Phone cannot be empty!': null,
onChanged: (value) {
setState(() => phone = value);
},
),
SizedBox(height: 10.0),
TextFormField(
decoration: InputDecoration(
hintText: 'Unique ID ',
border: OutlineInputBorder(borderRadius: BorderRadius.circular(5))),
keyboardType: TextInputType.number,
validator: (value) => value.isEmpty ? 'Ic number cannot be empty!': null,
onChanged: (value) {
setState(() => uniqueID = value);
},
),
const SizedBox(height: 20.0),
RaisedButton(
color: Colors.redAccent,
textColor: Colors.black,
child: Text("Update"),
onPressed: () async {
if(_formKey.currentState.validate()){
_formKey.currentState.save();
} else {
print("Validator are correct!");
}
}
),
],
),
),
);
}
)
);
}
}
家庭主管class
import 'package:flutter/material.dart';
import 'package:finalyearproject/model/NewUser.dart';
import 'package:finalyearproject/screen/crud/UpdateSupervisor.dart';
import 'package:finalyearproject/screen/crud/AddSupervisor.dart';
import 'package:finalyearproject/service/database.dart';
import 'package:finalyearproject/sidebar/AdminDrawer.dart';
class HomeSupervisor extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.redAccent,
title: Text('Supervisor'),
actions: <Widget>[
IconButton(
icon: Icon(
Icons.add,
color: Colors.white,
),
onPressed: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) => AddSupervisor()));
})
],
),
drawer: AdminDrawer(),
body: ListSupervisor(),
);
}
}
class ListSupervisor extends StatefulWidget {
@override
_ListSupervisorState createState() => _ListSupervisorState();
}
class _ListSupervisorState extends State<ListSupervisor> {
NewUser user;
@override
Widget build(BuildContext context) {
return Container(
child: FutureBuilder(
future: DatabaseService().getPost(),
builder: (_, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(
child: Text("Loading..."),
);
} else {
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (_, index) {
return Card(
child: ListTile(
title: Container(
alignment: Alignment.centerLeft,
child: Column(
children: <Widget>[
SizedBox(height: 5.0),
Container(alignment: Alignment.centerLeft,
child: Text(
snapshot.data[index].data["name"]),
),
SizedBox(height: 5.0),
Container(alignment: Alignment.centerLeft,
child: Text(
snapshot.data[index].data["email"]),
),
SizedBox(height: 5.0),
Container(alignment: Alignment.centerLeft,
child: Text(
snapshot.data[index].data["uniqueID"]),
),
],
),
),
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
IconButton(
icon: Icon(Icons.delete),
color: Colors.red,
onPressed: (){
}
),
IconButton(
icon: Icon(Icons.edit),
color: Colors.black,
onPressed: () {
Navigator.push(context, MaterialPageRoute(builder: (context) => UpdateSupervisor())); //here the line error show//
}
),
IconButton(
icon: Icon(Icons.share),
onPressed: () {
}
),
],
)
),
);
});
}
}),
);
}
}
然后 erorr 显示,在行 96:101 where Iconbutton which i nagivator.push 到 UpdateSupervisor。
所以我的问题是如何将流提供程序包装在 onPressed() 中?
错误:在此 UpdateSupervisor 小部件上方找不到正确的提供者
要修复,请:
- 确保提供者是此 UpdateSupervisor 小部件的祖先
- 向 Provider 提供类型
- 为消费者提供类型
- 为 Provider.of()
提供类型
- 始终使用包导入。例如:`导入 'package:my_app/my_code.dart';
- 确保使用正确的
context
。
如果 none 这些解决方案有效,请在以下位置提交错误:
https://github.com/rrousselGit/provider/issues
导致错误的相关小部件是:
UpdateSupervisor file:///D:/Android_project/finalyearproject/lib/screen/home/HomeSupervisor.dart:96:101
像这样用提供程序包装 MaterialApp。
ChangeNotifierProvider<NewUser>(create: (context) => NewUser(),
child: MaterialApp(
title: 'Flutter Demo',
home:Home(),
),
);
另外:
我正在使用 ChangeNotifierProvider 因为我假设您的提供商正在扩展 ChangeNotifier.
如果您不扩展 ChangeNotifier 您可以使用以下提供程序的基本形式:
Provider<NewUser>(
create: (context) => NewUser(),
child: child: MaterialApp(
title: 'Flutter Demo',
home:Home(),
),
)
这将使您有可能使用 NewUser 对象作为所有 Provider 后代 类 的依赖注入,例如这个:
class HomeWidget extends StatelessWidget {
@override
Widget buid(BuildContext context){
final provider = Provider.of<NewUser>(contextm, listen:false); /// you can to not set listen on false it does not matter in this case cause this type of provider is just an injection
return Text(provider.someText);
}
}
还有 StreamProvider 让你在流中收听并更新 Widget 当流接收数据时注入这个提供者,也检查一下。
还有一个 MultiProvider 让你用多个 Provider 包装 MaterialApp。
还要检查这个url
来自 flutter.dev
的 MultiProvider 示例
void main() {
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider(create: (context) => CartModel()),
Provider(create: (context) => SomeOtherClass()),
],
child: MyApp(),
),
);
}
如何将流提供者包装在 onPressed 函数中?这是我的 class.
更新主管class
import 'package:finalyearproject/model/NewUser.dart';
import 'package:finalyearproject/service/database.dart';
import 'package:finalyearproject/shared/Loading.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class UpdateSupervisor extends StatefulWidget {
@override
_UpdateSupervisorState createState() => _UpdateSupervisorState();
}
class _UpdateSupervisorState extends State<UpdateSupervisor> {
// form values
String name;
String email;
String uniqueID;
String phone;
String id;
final GlobalKey<FormState> _formKey = GlobalKey();
@override
Widget build(BuildContext context) {
final user = Provider.of<NewUser>(context);
return Scaffold(
appBar: AppBar(
title: Text('Edit Supervisor'),
backgroundColor: Colors.redAccent,
),
body: StreamBuilder(
stream: DatabaseService(uid: user.id).userData,
builder: (context, snapshot){
if(!snapshot.hasData){
return Loading();
}
NewUser userData = snapshot.data;
return Form(
key: _formKey,
child: SingleChildScrollView(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
SizedBox(height: 25.0),
TextFormField(
decoration: InputDecoration(
hintText: 'Name',
border: OutlineInputBorder(borderRadius: BorderRadius.circular(5))),
keyboardType: TextInputType.text,
initialValue: userData.name,
validator: (value) => value.isEmpty ? 'Name cannot be empty!': null,
onChanged: (value) {
setState(() => name = value);
},
),
SizedBox(height: 10.0),
TextFormField(
decoration: InputDecoration(
hintText: 'Email',
border: OutlineInputBorder(borderRadius: BorderRadius.circular(5))),
keyboardType: TextInputType.emailAddress,
validator: (value) => value.isEmpty ? 'Email cannot be empty!': null,
onChanged: (value) {
setState(() => email = value);
},
),
SizedBox(height: 10.0),
TextFormField(
decoration: InputDecoration(
hintText: 'Number Phone',
border: OutlineInputBorder(borderRadius: BorderRadius.circular(5))),
keyboardType: TextInputType.number,
validator: (value) => value.isEmpty ? 'Number Phone cannot be empty!': null,
onChanged: (value) {
setState(() => phone = value);
},
),
SizedBox(height: 10.0),
TextFormField(
decoration: InputDecoration(
hintText: 'Unique ID ',
border: OutlineInputBorder(borderRadius: BorderRadius.circular(5))),
keyboardType: TextInputType.number,
validator: (value) => value.isEmpty ? 'Ic number cannot be empty!': null,
onChanged: (value) {
setState(() => uniqueID = value);
},
),
const SizedBox(height: 20.0),
RaisedButton(
color: Colors.redAccent,
textColor: Colors.black,
child: Text("Update"),
onPressed: () async {
if(_formKey.currentState.validate()){
_formKey.currentState.save();
} else {
print("Validator are correct!");
}
}
),
],
),
),
);
}
)
);
}
}
家庭主管class
import 'package:flutter/material.dart';
import 'package:finalyearproject/model/NewUser.dart';
import 'package:finalyearproject/screen/crud/UpdateSupervisor.dart';
import 'package:finalyearproject/screen/crud/AddSupervisor.dart';
import 'package:finalyearproject/service/database.dart';
import 'package:finalyearproject/sidebar/AdminDrawer.dart';
class HomeSupervisor extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.redAccent,
title: Text('Supervisor'),
actions: <Widget>[
IconButton(
icon: Icon(
Icons.add,
color: Colors.white,
),
onPressed: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) => AddSupervisor()));
})
],
),
drawer: AdminDrawer(),
body: ListSupervisor(),
);
}
}
class ListSupervisor extends StatefulWidget {
@override
_ListSupervisorState createState() => _ListSupervisorState();
}
class _ListSupervisorState extends State<ListSupervisor> {
NewUser user;
@override
Widget build(BuildContext context) {
return Container(
child: FutureBuilder(
future: DatabaseService().getPost(),
builder: (_, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(
child: Text("Loading..."),
);
} else {
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (_, index) {
return Card(
child: ListTile(
title: Container(
alignment: Alignment.centerLeft,
child: Column(
children: <Widget>[
SizedBox(height: 5.0),
Container(alignment: Alignment.centerLeft,
child: Text(
snapshot.data[index].data["name"]),
),
SizedBox(height: 5.0),
Container(alignment: Alignment.centerLeft,
child: Text(
snapshot.data[index].data["email"]),
),
SizedBox(height: 5.0),
Container(alignment: Alignment.centerLeft,
child: Text(
snapshot.data[index].data["uniqueID"]),
),
],
),
),
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
IconButton(
icon: Icon(Icons.delete),
color: Colors.red,
onPressed: (){
}
),
IconButton(
icon: Icon(Icons.edit),
color: Colors.black,
onPressed: () {
Navigator.push(context, MaterialPageRoute(builder: (context) => UpdateSupervisor())); //here the line error show//
}
),
IconButton(
icon: Icon(Icons.share),
onPressed: () {
}
),
],
)
),
);
});
}
}),
);
}
}
然后 erorr 显示,在行 96:101 where Iconbutton which i nagivator.push 到 UpdateSupervisor。 所以我的问题是如何将流提供程序包装在 onPressed() 中?
错误:在此 UpdateSupervisor 小部件上方找不到正确的提供者
要修复,请:
- 确保提供者是此 UpdateSupervisor 小部件的祖先
- 向 Provider 提供类型
- 为消费者提供类型
- 为 Provider.of() 提供类型
- 始终使用包导入。例如:`导入 'package:my_app/my_code.dart';
- 确保使用正确的
context
。
如果 none 这些解决方案有效,请在以下位置提交错误: https://github.com/rrousselGit/provider/issues 导致错误的相关小部件是: UpdateSupervisor file:///D:/Android_project/finalyearproject/lib/screen/home/HomeSupervisor.dart:96:101
像这样用提供程序包装 MaterialApp。
ChangeNotifierProvider<NewUser>(create: (context) => NewUser(),
child: MaterialApp(
title: 'Flutter Demo',
home:Home(),
),
);
另外: 我正在使用 ChangeNotifierProvider 因为我假设您的提供商正在扩展 ChangeNotifier.
如果您不扩展 ChangeNotifier 您可以使用以下提供程序的基本形式:
Provider<NewUser>(
create: (context) => NewUser(),
child: child: MaterialApp(
title: 'Flutter Demo',
home:Home(),
),
)
这将使您有可能使用 NewUser 对象作为所有 Provider 后代 类 的依赖注入,例如这个:
class HomeWidget extends StatelessWidget {
@override
Widget buid(BuildContext context){
final provider = Provider.of<NewUser>(contextm, listen:false); /// you can to not set listen on false it does not matter in this case cause this type of provider is just an injection
return Text(provider.someText);
}
}
还有 StreamProvider 让你在流中收听并更新 Widget 当流接收数据时注入这个提供者,也检查一下。
还有一个 MultiProvider 让你用多个 Provider 包装 MaterialApp。
还要检查这个url
来自 flutter.dev
的 MultiProvider 示例void main() {
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider(create: (context) => CartModel()),
Provider(create: (context) => SomeOtherClass()),
],
child: MyApp(),
),
);
}