如何解决Flutter 中使用 ChangeNotifierProvider 在页面之间传输数据
我正在使用 Flutter 开发应用程序。我把屏幕分成两半。屏幕上方有按钮。当您按下这些按钮时,屏幕底部的页面会发生变化。 我使用 ChangeNotifierProvider 来完成这项工作。但它给出了以下错误。没有打开管理面板,它会通过将屏幕涂成红色来显示此错误。
我还查看了会导致此错误的情况,它们都没有问题。我不明白错误在哪里。
谁能帮我修复代码?
错误信息:
错误:在此 AdminHomePage 小部件上方找不到正确的提供程序
发生这种情况是因为您使用了不包含您选择的提供程序的 BuildContext
。有几种常见的情况:
- 您在
main.dart
中添加了一个新的提供程序并执行了热重新加载。要修复,请执行热重启。 - 您尝试读取的提供程序位于不同的路径中。 提供者是“有范围的”。因此,如果您在路由中插入提供者,则其他路由将无法访问该提供者。
- 您使用了
BuildContext
,它是您尝试读取的提供程序的祖先。 确保 AdminHomePage 在您的 MultiProvider/Provider 下。这通常发生在您创建提供程序并尝试立即读取它时。
构成屏幕图像的代码(相关代码行:3.4.15.71.86.)=
void main() {
runApp(
ChangeNotifierProvider<StateAltMenuData>(
create: (BuildContext context) => StateAltMenuData(),child: MaterialApp(
home: AdminHomePage(),),);
}
class AdminHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
Function altMenu = Provider.of<StateAltMenuData>(context).altMenuDegistir;
final screenHeight = MediaQuery.of(context).size.height;
return Scaffold(
body: Column(
children: <Widget>[
Expanded(
flex: 3,child: Stack(
children: <Widget>[
OpaqueImage(
color: primaryColorOpacity.withOpacity(0.85),imageUrl: "assets/images/kitap_arkaplan.jpg",SafeArea(
child: Padding(
padding: const EdgeInsets.all(4),child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,children: [
Align(
alignment: Alignment.centerLeft,child: IconButton(
icon: const Icon(Icons.star),color: Colors.white,onPressed: () {
Navigator.pushAndRemoveUntil(
context,PageTransition(
type: PageTransitionType.fade,child: UserHomePage()),(Route<dynamic> route) => false);
},Align(
alignment: Alignment.topCenter,child: Text(
"Yönetici Sayfası",textAlign: TextAlign.center,style: headingTextStyle,Align(
alignment: Alignment.centerRight,child: IconButton(
icon: const Icon(
Icons.supervisor_account_rounded),onPressed: () {},],ControlButtons(),Expanded(
flex: 5,child: SingleChildScrollView(
child: Container(
height: screenHeight * (5 / 8),padding: const EdgeInsets.only(top: 0),child: altMenu(),);
}
}
保存状态信息的代码 =
class StateAltMenuData with ChangeNotifier {
int altMenuIndex = 1;
altMenuDegistir(int yeniIndex) {
altMenuIndex = yeniIndex;
notifyListeners();
switch (yeniIndex) {
case 1:
return Kutuphane();
break;
case 2:
return KitapAra();
break;
case 3:
return TalebeEkle();
break;
case 4:
return TalebeAra();
break;
default:
return Container(
child: Center(
child: Text("Bir şeyler ters gitti."),);
}
}
}
按钮代码(相关代码行:4.11.23.39.51.)=
class ControlButtons extends StatelessWidget {
@override
Widget build(BuildContext context) {
Function yeniIndex = Provider.of<StateAltMenuData>(context).altMenuDegistir;
return Table(
children: [
TableRow(
children: [
GestureDetector(
onTap: () {
yeniIndex(1);
},child: ControlButtonCard(
icon: Icon(
Icons.add_circle_outline_rounded,color: Colors.blue,text: "Kütüphane",GestureDetector(
onTap: () {
yeniIndex(2);
},child: ControlButtonCard(
icon: Icon(
Icons.search_rounded,text: "Kitap Ara",TableRow(
children: [
GestureDetector(
onTap: () {
yeniIndex(3);
},child: ControlButtonCard(
icon: Icon(
Icons.person_add,text: "Talebe Ekle",GestureDetector(
onTap: () {
yeniIndex(4);
},child: ControlButtonCard(
icon: Icon(
Icons.person_search,text: "Talebe Ara",);
}
}
解决方法
在这里查看我对另一个问题的回答Provider to a different page not working as excpected
如果还有问题,请告诉我。
,我已经解决了这个问题。我在某处看不到解决方案。我已经工作了三四天了。也许它会帮助某人,不像我那么难。我把解决方案留在这里。
1- 我注意到我从用户面板切换到管理面板时运行的函数不在 ChangeNotifierProvider 中。我是这样做的:
我使用 ChangeNotifierProvider 包装了名为 AdminHomePage 的无状态小部件,并向子项返回了一个名为 AdminPage 的新类。
void main () (
runApp (
MaterialApp (
home: AdminHomePage (),),);
}
class AdminHomePage extends StatelessWidget {
@override
Widget build (BuildContext context) {
return ChangeNotifierProvider <StateAltMenuData> (
create: (BuildContext context) => StateAltMenuData (),child: AdminPage ());
}
}
class AdminPage extends StatelessWidget {
@override
Widget build (BuildContext context) {
int altMenuIndex = Provider.of <StateAltMenuData> (context) .altMenuIndex;
final screenHeight = MediaQuery.of (context) .size.height;
return Scaffold (
body: Column (
2- 这样做之后,另一个问题出现了。将在上面第 86 行显示图像的函数要求我提供一个动态值,我将其返回为空。我是这样解决的:
我在 AdminPage 中分配了一个名为 altMenuIndex 的变量。此变量的值调用 StateAltMenuData 中的 altMenuIndex。这已经被按钮上的值所采用。
int altMenuIndex = Provider.of <StateAltMenuData> (context) .altMenuIndex;
3- 我将 StateAltMenuData 的内部更改如下。我创建了两个不同的函数变量。所以我可以在不同的地方调用不同的函数。
class StateAltMenuData with ChangeNotifier {
int altMenuIndex = 1;
void change altMenuIndex (int newIndex) (
altMenuIndex = newIndex;
notifyListeners ();
}
Change subMenu (subMenuIndex) (
switch (subMenuIndex) (
case 1:
return Library ();
break;
case 2:
return Search Book ();
break;
case 3:
return Add to Request ();
break;
case 4:
returnCall Request ();
break;
default:
return Container (
child: Center (
child: Text ("Something went wrong"),);
}
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。