Flutter中使用ChangeNotifierProvider在页面间传递数据
Data transfer between pages with ChangeNotifierProvider in Flutter
我正在使用 Flutter 开发应用程序。我把屏幕分成两半。屏幕上方有按钮。当您按下这些按钮时,屏幕底部的页面将会改变。
我使用 ChangeNotifierProvider 来完成这项工作。但它给出了以下错误。在不打开管理面板的情况下,它通过将屏幕涂成红色来给出此错误。
我也看过会导致这个错误的情况,none其中有问题。我不明白到底哪里出错了。
谁能帮我修改代码?
错误信息:
错误:在此 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),
color: Colors.white,
onPressed: () {},
),
),
],
),
ControlButtons(),
],
),
),
),
],
),
),
Expanded(
flex: 5,
child: SingleChildScrollView(
child: Container(
height: screenHeight * (5 / 8),
padding: const EdgeInsets.only(top: 0),
color: Colors.white,
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,
color: Colors.blue,
),
text: "Kitap Ara",
),
),
],
),
TableRow(
children: [
GestureDetector(
onTap: () {
yeniIndex(3);
},
child: ControlButtonCard(
icon: Icon(
Icons.person_add,
color: Colors.blue,
),
text: "Talebe Ekle",
),
),
GestureDetector(
onTap: () {
yeniIndex(4);
},
child: ControlButtonCard(
icon: Icon(
Icons.person_search,
color: Colors.blue,
),
text: "Talebe Ara",
),
),
],
),
],
);
}
}
在这里检查我对另一个问题的回答Provider to a different page not working as excpected
如果仍然有问题,请告诉我。
我已经解决了问题。我在某处看不到解决方案。我已经工作了三四天了。也许它会帮助某人,而不是像我一样努力。我把解决方案留在这里。
1- 我注意到我 运行 从用户面板切换到管理面板时的功能不在 ChangeNotifierProvider 中。我是这样做的:
我用 ChangeNotifierProvider 包装了名为 AdminHomePage 的无状态小部件,并返回了一个名为 AdminPage 的新 class 到 child。
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"),
),
);
}
}
}
我正在使用 Flutter 开发应用程序。我把屏幕分成两半。屏幕上方有按钮。当您按下这些按钮时,屏幕底部的页面将会改变。 我使用 ChangeNotifierProvider 来完成这项工作。但它给出了以下错误。在不打开管理面板的情况下,它通过将屏幕涂成红色来给出此错误。
我也看过会导致这个错误的情况,none其中有问题。我不明白到底哪里出错了。
谁能帮我修改代码?
错误信息:
错误:在此 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),
color: Colors.white,
onPressed: () {},
),
),
],
),
ControlButtons(),
],
),
),
),
],
),
),
Expanded(
flex: 5,
child: SingleChildScrollView(
child: Container(
height: screenHeight * (5 / 8),
padding: const EdgeInsets.only(top: 0),
color: Colors.white,
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,
color: Colors.blue,
),
text: "Kitap Ara",
),
),
],
),
TableRow(
children: [
GestureDetector(
onTap: () {
yeniIndex(3);
},
child: ControlButtonCard(
icon: Icon(
Icons.person_add,
color: Colors.blue,
),
text: "Talebe Ekle",
),
),
GestureDetector(
onTap: () {
yeniIndex(4);
},
child: ControlButtonCard(
icon: Icon(
Icons.person_search,
color: Colors.blue,
),
text: "Talebe Ara",
),
),
],
),
],
);
}
}
在这里检查我对另一个问题的回答Provider to a different page not working as excpected
如果仍然有问题,请告诉我。
我已经解决了问题。我在某处看不到解决方案。我已经工作了三四天了。也许它会帮助某人,而不是像我一样努力。我把解决方案留在这里。
1- 我注意到我 运行 从用户面板切换到管理面板时的功能不在 ChangeNotifierProvider 中。我是这样做的:
我用 ChangeNotifierProvider 包装了名为 AdminHomePage 的无状态小部件,并返回了一个名为 AdminPage 的新 class 到 child。
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"),
),
);
}
}
}