我有卡片列表。当我点击卡片时,BoxViewPage打开。
如果同时使用Hero和多提供程序,则会出现错误,
但是,
如果我分别使用Hero和MultiProvider,一切都能正常工作
为什么?
卡片清单:
return Hero(
tag: box.ID,
child: InkWell(
child: selectBoxSize(viewType),
onTap: () async {
Navigator.of(context).push(
MaterialPageRoute(
builder: (BuildContext context) => MultiProvider(
providers: [
ChangeNotifierProvider<Archive>.value(value: archive),
ChangeNotifierProvider<Box>.value(value: box),
],
builder: (context, child) => BoxViewPage(),
),
),
内部框视图页:
class BoxCardView extends StatefulWidget {
const BoxCardView({Key key}) : super(key: key);
@override
_BoxCardViewState createState() => _BoxCardViewState();
}
class _BoxCardViewState extends State<BoxCardView> {
@override
Widget build(BuildContext context) {
final box = Provider.of<Box>(context);
return Hero(
tag: box.ID,
child: Card(
clipBehavior: Clip.antiAlias,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12.0),
),
margin: EdgeInsets.all(12),
child: Column(
children: <Widget>[
Expanded(child: WidgetEditPhotosScrollHoriz()),
WidgetNameDescrTagsEdit(),
],
),
),
);
}
}
错误:
如果验证未找到提供程序异常(错误:在此Widget EditPhotosScrollHoriz Widget上方找不到正确的提供者
这是因为您使用的BuildContext
不包含您选择的提供程序。
- 您在
main.dart
中添加了新的提供程序并执行了热重新加载。要修复此问题,请执行热重新启动。 - 您尝试读取的提供程序位于不同的路由中。
提供者是“有范围的”。所以如果你在一个路由中插入一个提供者,那么其他路由将无法访问这个提供者。
- 您使用的
BuildContext
是您尝试读取之提供者的上阶。
确保WidgetEditPhotosScrollHoriz位于MultiProvider/Provider下。这通常发生在创建提供程序并尝试立即读取它时。
例如,取代:
Widget build(BuildContext context) {
return Provider<Example>(
create: (_) => Example(),
// Will throw a ProviderNotFoundError, because `context` is associated
// to the widget that is the parent of `Provider<Example>`
child: Text(context.watch<Example>()),
),
}
考虑如下使用builder
:
Widget build(BuildContext context) {
return Provider<Example>(
create: (_) => Example(),
// we use `builder` to obtain a new `BuildContext` that has access to the provider
builder: (context) {
// No longer throws
return Text(context.watch<Example>()),
}
),
}
如果这些解决方案都不起作用,请考虑寻求有关StackOverflow的帮助:(第10页)
3条答案
按热度按时间pdsfdshx1#
据我所知,我认为你的问题也是一个典型的,而使用提供商。
我总是建议在应用程序的根目录下使用provider(在MaterialApp之上),这主要是使用它而不会遇到错误的最佳方式。
您可以看到这里实际发生了什么,提供程序基于层次结构工作(它们为所有的小部件和子小部件提供了一个特定的值),我相信你也期待着这一点,但是当我们使用导航器而不是小部件之间的父子关系时,它更像是页面之间的兄弟关系。注意,我在这里使用了页面这个词。当您导航到当前位于导航堆栈顶部的新页面时,您案例中的提供程序仅向您使用它的特定页面的子小部件提供值,而该页面不是子小部件,而是一种同级关系,因此您无法在此处访问提供程序。
如果您不明白这一点,请不要担心,最简单的解决方案和可视化方法就是在浏览器上打开dart开发工具,在Widget Inspector中,检查Widget层次结构,您会发现您要使用提供程序提供的值的Widget不在该层次结构之下,现在您只需要弄清楚您应该做什么来实现它。
我可以给予的一个解决方案是在应用程序的根(Above MaterialApp)使用提供程序。
pxy2qtax2#
你能在你的卡片列表文件中试试这个吗:
cngwdvgl3#
我终于解决了从供应商切换到riverpod,它的工作也很好与英雄。谢谢
https://pub.dev/packages/riverpod