使用 Hero 动画 Flutter 找不到正确的 Provider<>

nic*_*er 5 provider navigator dart flutter flutter-change-notifier

我正在将图库文件中的新内容推Route送到带有动画的详细信息文件中Hero。一切都很好,但是当我调用pop()详细信息文件内部以返回图库时,出现错误Provider

\n
flutter: \xe2\x95\x90\xe2\x95\x90\xe2\x95\xa1 EXCEPTION CAUGHT BY WIDGETS LIBRARY \xe2\x95\x9e\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\nflutter: The following ProviderNotFoundException was thrown building GalleryThumbnail(dirty, state:\nflutter: _GalleryThumbnailState#9dc96):\nflutter: Error: Could not find the correct Provider<GalleryViewModel> above this GalleryThumbnail Widget\n
Run Code Online (Sandbox Code Playgroud)\n

这是我的画廊文件:

\n
@override\n  Widget build(BuildContext context) {\n    return MultiProvider(\n        providers: [\n          ChangeNotifierProvider.value(value: galleryViewModel),\n          ChangeNotifierProvider.value(value: galleryProvider)\n        ],\n        child: Scaffold(\n            resizeToAvoidBottomInset: false,\n            body: Stack(\n              children: [\n                Consumer<GalleryViewModel>(\n                    builder: (context, model, child) =>\n                        galleryViewModel.assetsList.length != 0 ? gallery() : emptyGallery()),\n\n...\n\n}\n\n\nWidget gallery() {\n    return Container(\n      padding: EdgeInsets.only(left: 5, right: 5, top: 5),\n      child: CupertinoScrollbar(\n        child: GridView.builder(\n          gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(\n              crossAxisCount: 3,\n              crossAxisSpacing: 2,\n              mainAxisSpacing: 2,\n              childAspectRatio: 0.85,\n            ),\n          itemCount: galleryViewModel.assetsList.length,\n          padding: EdgeInsets.only(bottom: Constants.navBarSize),\n          physics: BouncingScrollPhysics(),\n          shrinkWrap: true,\n          itemBuilder: (context, index) {\n            if(index >= galleryViewModel.assetsList.length-30) {\n              galleryViewModel.onLoadMore(index);\n            }\n            return _galleryItem(index);\n          },\n\n        ),\n      ),\n    );\n  }\n\n\nWidget _galleryItem(int index) {\n    return Stack(\n      children: [\n        Consumer<GalleryProvider>(\n          builder: (context, model, child) {\n            return Container(\n              padding:\n                  multipleSelection ? EdgeInsets.all(2) : EdgeInsets.all(0),\n              decoration: multipleSelection ? BoxDecoration(\n                      borderRadius: BorderRadius.circular(20),\n                      border: Border.all(color: Colors.transparent , width: 2)) : BoxDecoration(),\n              child: child,\n            );\n          },\n            Hero(\n            createRectTween: (Rect? begin, Rect? end) {\n              RectTween _rectTween =\n              RectTween(begin: begin, end: end);\n              return _rectTween;\n            },\n            tag: galleryViewModel.assetsList[index].id,\n            child:\n          child: GalleryThumbnail(\n            asset: galleryViewModel.assetsList[index],\n           \n            onTap: (data) {\n              Navigator.push(context, MaterialPageRoute(builder: (context) {\n                  return MediaEditorPage(\n                      asset: galleryViewModel.assetsList[index],\n                      bytes: data);\n                }));\n            },\n          ),\n\n\n...\n\n}\n\n
Run Code Online (Sandbox Code Playgroud)\n

当我在没有英雄或其他路线的情况下进行推送时,没有错误,我不明白为什么在英雄上方找不到提供者,在导航器转换时我没有通知任何提供者。

\n

为什么我在这里收到提供商错误以及如何解决此问题?

\n

谢谢你的帮助

\n

Tom*_*652 3

使用Herowidget时,似乎出现了Context问题。

这意味着当动画执行时,并且在您调用 a 的目标中Provider.of<Model>(context),它将找不到正确的Provider.

您只需按照Navigator示例中给出的 a 进行操作即可:

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);
                }));
      },
    ),
  ),
)
Run Code Online (Sandbox Code Playgroud)

我添加了:ChangeNotifierProvider.value(value: galleryViewModel)包装GalleryThumbnail.