I'm pushing a new Route
in my Gallery file to the Details file with a Hero
animation. Everything is fine but when I'm calling the pop()
inside the details file to go back to Gallery, I have a Provider
error :
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
Here is my gallery file :
@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);
}));
},
),
...
}
When I'm pushing without the hero or another route there is no error and I don't why the provider could not be find above the Hero, I'm not notifying any provider while navigator transitions.
Why I'm getting a provider error here and how to fix this ?
Thanks for any help
When using Hero
widget, it seems there is a Context
issue.
This means that when the animation is performing, and in the destination you are calling a Provider.of<Model>(context)
, it will not find the correct Provider
.
You simply need to do as you would do with a Navigator
which gives in your example :
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);
}));
},
),
),
)
I have added : ChangeNotifierProvider.value(value: galleryViewModel)
wrapping the GalleryThumbnail
.