无法使用 Hero 动画 Flutter 找到正确的 Provider<>
Could not find the correct Provider<> with Hero animation Flutter
我正在将我的图库文件中的新 Route
推送到包含 Hero
动画的详细信息文件。一切都很好,但是当我在详细信息文件中调用 pop()
返回图库时,出现 Provider
错误:
flutter: ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
flutter: The following ProviderNotFoundException was thrown building GalleryThumbnail(dirty, state:
flutter: _GalleryThumbnailState#9dc96):
flutter: Error: Could not find the correct Provider<GalleryViewModel> above this GalleryThumbnail Widget
这是我的图库文件:
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider.value(value: galleryViewModel),
ChangeNotifierProvider.value(value: galleryProvider)
],
child: Scaffold(
resizeToAvoidBottomInset: false,
body: Stack(
children: [
Consumer<GalleryViewModel>(
builder: (context, model, child) =>
galleryViewModel.assetsList.length != 0 ? gallery() : emptyGallery()),
...
}
Widget gallery() {
return Container(
padding: EdgeInsets.only(left: 5, right: 5, top: 5),
child: CupertinoScrollbar(
child: GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
crossAxisSpacing: 2,
mainAxisSpacing: 2,
childAspectRatio: 0.85,
),
itemCount: galleryViewModel.assetsList.length,
padding: EdgeInsets.only(bottom: Constants.navBarSize),
physics: BouncingScrollPhysics(),
shrinkWrap: true,
itemBuilder: (context, index) {
if(index >= galleryViewModel.assetsList.length-30) {
galleryViewModel.onLoadMore(index);
}
return _galleryItem(index);
},
),
),
);
}
Widget _galleryItem(int index) {
return Stack(
children: [
Consumer<GalleryProvider>(
builder: (context, model, child) {
return Container(
padding:
multipleSelection ? EdgeInsets.all(2) : EdgeInsets.all(0),
decoration: multipleSelection ? BoxDecoration(
borderRadius: BorderRadius.circular(20),
border: Border.all(color: Colors.transparent , width: 2)) : BoxDecoration(),
child: child,
);
},
Hero(
createRectTween: (Rect? begin, Rect? end) {
RectTween _rectTween =
RectTween(begin: begin, end: end);
return _rectTween;
},
tag: galleryViewModel.assetsList[index].id,
child:
child: GalleryThumbnail(
asset: galleryViewModel.assetsList[index],
onTap: (data) {
Navigator.push(context, MaterialPageRoute(builder: (context) {
return MediaEditorPage(
asset: galleryViewModel.assetsList[index],
bytes: data);
}));
},
),
...
}
当我在没有英雄或其他路线的情况下推送时,没有错误,而且我不知道为什么在英雄上方找不到提供者,我在导航器转换时没有通知任何提供者。
为什么我在此处收到提供程序错误以及如何解决此问题?
感谢您的帮助
使用 Hero
小部件时,似乎存在 Context
问题。
这意味着当动画正在执行时,在您调用 Provider.of<Model>(context)
的目标中,它不会找到正确的 Provider
。
您只需要按照在示例中给出的 Navigator
执行的操作即可:
Hero(
createRectTween: (Rect? begin, Rect? end) {
RectTween _rectTween =
RectTween(begin: begin, end: end);
return _rectTween;
},
tag: galleryViewModel.assetsList[index].id,
child: ChangeNotifierProvider.value(
value: galleryViewModel,
child: GalleryThumbnail(
asset: galleryViewModel.assetsList[index],
size: size,
onLongPress: () {
if (!multipleSelection) {
multipleSelection = true;
galleryViewModel.selectedAssets.add(galleryViewModel.assetsList[index]);
galleryProvider.notify();
}
},
onTap: (data) {
Navigator.push(context, MaterialPageRoute(builder: (context) {
return MediaEditorPage(
asset: galleryViewModel.assetsList[index],
bytes: data);
}));
},
),
),
)
我添加了:ChangeNotifierProvider.value(value: galleryViewModel)
包装 GalleryThumbnail
。
我正在将我的图库文件中的新 Route
推送到包含 Hero
动画的详细信息文件。一切都很好,但是当我在详细信息文件中调用 pop()
返回图库时,出现 Provider
错误:
flutter: ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
flutter: The following ProviderNotFoundException was thrown building GalleryThumbnail(dirty, state:
flutter: _GalleryThumbnailState#9dc96):
flutter: Error: Could not find the correct Provider<GalleryViewModel> above this GalleryThumbnail Widget
这是我的图库文件:
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider.value(value: galleryViewModel),
ChangeNotifierProvider.value(value: galleryProvider)
],
child: Scaffold(
resizeToAvoidBottomInset: false,
body: Stack(
children: [
Consumer<GalleryViewModel>(
builder: (context, model, child) =>
galleryViewModel.assetsList.length != 0 ? gallery() : emptyGallery()),
...
}
Widget gallery() {
return Container(
padding: EdgeInsets.only(left: 5, right: 5, top: 5),
child: CupertinoScrollbar(
child: GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
crossAxisSpacing: 2,
mainAxisSpacing: 2,
childAspectRatio: 0.85,
),
itemCount: galleryViewModel.assetsList.length,
padding: EdgeInsets.only(bottom: Constants.navBarSize),
physics: BouncingScrollPhysics(),
shrinkWrap: true,
itemBuilder: (context, index) {
if(index >= galleryViewModel.assetsList.length-30) {
galleryViewModel.onLoadMore(index);
}
return _galleryItem(index);
},
),
),
);
}
Widget _galleryItem(int index) {
return Stack(
children: [
Consumer<GalleryProvider>(
builder: (context, model, child) {
return Container(
padding:
multipleSelection ? EdgeInsets.all(2) : EdgeInsets.all(0),
decoration: multipleSelection ? BoxDecoration(
borderRadius: BorderRadius.circular(20),
border: Border.all(color: Colors.transparent , width: 2)) : BoxDecoration(),
child: child,
);
},
Hero(
createRectTween: (Rect? begin, Rect? end) {
RectTween _rectTween =
RectTween(begin: begin, end: end);
return _rectTween;
},
tag: galleryViewModel.assetsList[index].id,
child:
child: GalleryThumbnail(
asset: galleryViewModel.assetsList[index],
onTap: (data) {
Navigator.push(context, MaterialPageRoute(builder: (context) {
return MediaEditorPage(
asset: galleryViewModel.assetsList[index],
bytes: data);
}));
},
),
...
}
当我在没有英雄或其他路线的情况下推送时,没有错误,而且我不知道为什么在英雄上方找不到提供者,我在导航器转换时没有通知任何提供者。
为什么我在此处收到提供程序错误以及如何解决此问题?
感谢您的帮助
使用 Hero
小部件时,似乎存在 Context
问题。
这意味着当动画正在执行时,在您调用 Provider.of<Model>(context)
的目标中,它不会找到正确的 Provider
。
您只需要按照在示例中给出的 Navigator
执行的操作即可:
Hero(
createRectTween: (Rect? begin, Rect? end) {
RectTween _rectTween =
RectTween(begin: begin, end: end);
return _rectTween;
},
tag: galleryViewModel.assetsList[index].id,
child: ChangeNotifierProvider.value(
value: galleryViewModel,
child: GalleryThumbnail(
asset: galleryViewModel.assetsList[index],
size: size,
onLongPress: () {
if (!multipleSelection) {
multipleSelection = true;
galleryViewModel.selectedAssets.add(galleryViewModel.assetsList[index]);
galleryProvider.notify();
}
},
onTap: (data) {
Navigator.push(context, MaterialPageRoute(builder: (context) {
return MediaEditorPage(
asset: galleryViewModel.assetsList[index],
bytes: data);
}));
},
),
),
)
我添加了:ChangeNotifierProvider.value(value: galleryViewModel)
包装 GalleryThumbnail
。