Flutter 提供程序在导航到另一个屏幕时失去价值
Flutter provider loosing value when navigating to another screen
我是 Flutter
和 provider package
的新手,所以任何帮助都会很好,所以我的 main.dart
文件如下所示:
void main() => runApp(
MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData.light(),
home: ChangeNotifierProvider(
create: (_) => InterestingMomentProvider(),
child: Home(),
),
),
);
这构建了我的 Home
小部件,我不会 post 全部,因为它非常大,但是,我点击一个按钮,它会将一个字符串传递给提供者 class 并将其添加到概述如下的列表中:
import 'package:flutter/widgets.dart';
class InterestingMomentProvider extends ChangeNotifier {
List<String> _moments = [];
List<String> get moments => _moments;
void addMoment(String time){
_moments.add(time);
}
int momentsTotal(){
return _moments.length;
}
}
在 addMoment 方法上添加断点我可以确认 _moments 包含所有字符串。
然后我按一个按钮导航到另一个屏幕,导航代码如下:
Navigator.push(context, MaterialPageRoute(builder: (context) => MomentsRecorded()),);
MomentsRecorded插件如下:
class MomentsRecorded extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Moments'),
centerTitle: true,
),
body: Center(
child: MomentsList()
),
);
}
}
第一个错误是:
Could not find the correct Provider<InterestingMomentProvider> above this Consumer<InterestingMomentProvider> Widget
To fix, please:
* Ensure the Provider<InterestingMomentProvider> is an ancestor to this Consumer<InterestingMomentProvider> Widget
* Provide types to Provider<InterestingMomentProvider>
* Provide types to Consumer<InterestingMomentProvider>
* Provide types to Provider.of<InterestingMomentProvider>()
* Always use package imports. Ex: `import 'package:my_app/my_code.dart';
* Ensure the correct `context` is being used.
然后我将正文调整为如下所示,错误消失了:
body: Center(
child: ChangeNotifierProvider(
create: (_) => InterestingMomentProvider(),
child: MomentsList())
),
但是在 MomentLists 小部件中,我尝试循环遍历来自提供程序 class 的时刻列表,但是当调试 _moments 为 0 时?
时刻列表小部件:
class MomentsList extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Consumer<InterestingMomentProvider>(
builder: (context, momentData, child){
return momentData.momentsTotal() > 0 ? ListView.builder(
itemCount: momentData.momentsTotal(),
itemBuilder: (BuildContext context, int index) {
final moment = momentData.moments[index];
return ListTile(
title: Text(moment),
);
}
) : Center(child: Text('no moments recorded'),);
}
);
}
}
有人可以解释为什么会这样吗?
发生这种情况,因为您的提供程序是在 MaterialApp
的 home
属性 中定义的,因此当您更改路由时,提供程序也会被删除。
解决方案:将提供程序移动到 MaterialApp 上方,如下所示:
void main() => runApp(
ChangeNotifierProvider(
create: (_) => InterestingMomentProvider(),
child: MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData.light(),
home: Home()
),
),
);
如果你担心这不对 - checkout the docs, they doing the same
我是 Flutter
和 provider package
的新手,所以任何帮助都会很好,所以我的 main.dart
文件如下所示:
void main() => runApp(
MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData.light(),
home: ChangeNotifierProvider(
create: (_) => InterestingMomentProvider(),
child: Home(),
),
),
);
这构建了我的 Home
小部件,我不会 post 全部,因为它非常大,但是,我点击一个按钮,它会将一个字符串传递给提供者 class 并将其添加到概述如下的列表中:
import 'package:flutter/widgets.dart';
class InterestingMomentProvider extends ChangeNotifier {
List<String> _moments = [];
List<String> get moments => _moments;
void addMoment(String time){
_moments.add(time);
}
int momentsTotal(){
return _moments.length;
}
}
在 addMoment 方法上添加断点我可以确认 _moments 包含所有字符串。
然后我按一个按钮导航到另一个屏幕,导航代码如下:
Navigator.push(context, MaterialPageRoute(builder: (context) => MomentsRecorded()),);
MomentsRecorded插件如下:
class MomentsRecorded extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Moments'),
centerTitle: true,
),
body: Center(
child: MomentsList()
),
);
}
}
第一个错误是:
Could not find the correct Provider<InterestingMomentProvider> above this Consumer<InterestingMomentProvider> Widget
To fix, please:
* Ensure the Provider<InterestingMomentProvider> is an ancestor to this Consumer<InterestingMomentProvider> Widget
* Provide types to Provider<InterestingMomentProvider>
* Provide types to Consumer<InterestingMomentProvider>
* Provide types to Provider.of<InterestingMomentProvider>()
* Always use package imports. Ex: `import 'package:my_app/my_code.dart';
* Ensure the correct `context` is being used.
然后我将正文调整为如下所示,错误消失了:
body: Center(
child: ChangeNotifierProvider(
create: (_) => InterestingMomentProvider(),
child: MomentsList())
),
但是在 MomentLists 小部件中,我尝试循环遍历来自提供程序 class 的时刻列表,但是当调试 _moments 为 0 时?
时刻列表小部件:
class MomentsList extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Consumer<InterestingMomentProvider>(
builder: (context, momentData, child){
return momentData.momentsTotal() > 0 ? ListView.builder(
itemCount: momentData.momentsTotal(),
itemBuilder: (BuildContext context, int index) {
final moment = momentData.moments[index];
return ListTile(
title: Text(moment),
);
}
) : Center(child: Text('no moments recorded'),);
}
);
}
}
有人可以解释为什么会这样吗?
发生这种情况,因为您的提供程序是在 MaterialApp
的 home
属性 中定义的,因此当您更改路由时,提供程序也会被删除。
解决方案:将提供程序移动到 MaterialApp 上方,如下所示:
void main() => runApp(
ChangeNotifierProvider(
create: (_) => InterestingMomentProvider(),
child: MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData.light(),
home: Home()
),
),
);
如果你担心这不对 - checkout the docs, they doing the same