Flutter 图片查看 photo_view

flutter查看图片的插件还是挺多的,我用的是 photo_view , 今天就和大家分享下我在使用这个插件过程中遇到的坑以及如何解决的。

首先引入插件:

photo_view: ^0.13.0

使用:

  Widget _buildPhotoView() {
    _galleryItems = [
      'assets/images/icon_avatar_staff.png',
      'assets/images/icon_avatar_staff.png',
      'assets/images/icon_avatar_staff.png'
    ];
    return PhotoViewGallery.builder(
      scrollPhysics: const BouncingScrollPhysics(),
      builder: (BuildContext context, int index) {
        return PhotoViewGalleryPageOptions(
          imageProvider: AssetImage(_galleryItems[index]),
          initialScale: PhotoViewComputedScale.contained * 0.9,
        );
      },
      itemCount: _galleryItems.length,
      backgroundDecoration: const BoxDecoration(color: Colors.white),
      pageController: PageController(initialPage: _currentPageIndex),
      onPageChanged: (i) {
        _currentPageIndex = i;
        _valueNotifier.notifyListeners();
      },
    );
  }

好了,代码写完了,使用还是比较简单的,万事俱备就差Run了,现在高高兴兴的连接测试机想看下效果,结果报错了,错误信息如下

问题:

======== Exception caught by image resource service ================================================
The following assertion was thrown resolving an image codec:
Unable to load asset: assets/images/icon_avatar_staff.png

When the exception was thrown, this was the stack: 
#0      PlatformAssetBundle.load (package:flutter/src/services/asset_bundle.dart:224:7)

#1      AssetBundleImageProvider._loadAsync (package:flutter/src/painting/image_provider.dart:675:14)

Image provider: AssetImage(bundle: null, name: "assets/images/icon_avatar_staff.png")
Image key: AssetBundleImageKey(bundle: PlatformAssetBundle#b17d1(), name: "assets/images/icon_avatar_staff.png", scale: 1.0)
====================================================================================================

找原因:

提示说没有找到这个图片资源,然后我就去查看我的配置文件


image.png

确实是配置了的啊,并且位置也是正确的,本贾震惊当时就真震惊了,然后我就开始从PhotoViewGalleryPageOptions(imageProvider:AssetImage(_galleryItems[index])这个构造方法一层一层的往下找,通过我不放弃、不抛弃的精神,最后在这个插件的源码里面看到了这个

  // retrieve image from the provider
  void _resolveImage() {
    final ImageStream newStream = widget.imageProvider.resolve(
      const ImageConfiguration(),   //就是它
    );
    _updateSourceStream(newStream);
  }

这里我们穿插一个小知识点哈:每个Flutter应用程序都有一个rootBundle对象, 可以轻松访问[主资源包],注意是主资源包。
然后我们再来看看上面 ImageConfiguration(),我们发现这个构造方法没有传AssetBundle,通过查看AssetImage的源码[final AssetBundle chosenBundle = bundle ?? configuration.bundle ?? rootBundle;]不难发现当bundle为null的时候就会使用程序的rootBundle,所以当我们使用PhotoViewGalleryPageOptions(imageProvider:AssetImage(_galleryItems[index])这个构造方法显示asset资源图片时,会通过rootBundle去访问asset主资源图。真相即将大白,现在再来看看我有添加主资源图吗,let me see see

image.png

拍断大腿,果然没有添加主资源图,只添加了2倍、3倍图。好吧,现在找到原因了,来看下解决办法吧,有2种方案哈,供大家参考:

解决问题:

  • Plan A: 差啥补啥
    添加主资源图


    image.png

    现在再Run一下,OK了,第一种方案完结撒花

  • Plan B: 自定义
    前面我们说过用的PhotoViewGalleryPageOptions(imageProvider:AssetImage(''))这个构造方法,会通过rootBundle去访问asset主资源图。如果我们不想添加主资源图,那我们就换方法,photo_view为我们提供了另一个自定义的构造方法

        // return PhotoViewGalleryPageOptions(
        //   imageProvider: AssetImage(_galleryItems[index]),
        //   initialScale: PhotoViewComputedScale.contained * 0.9,
        // );
        /// 对的,就是它
        return PhotoViewGalleryPageOptions.customChild(
          child: Image(
            image: AssetImage(_galleryItems[index]),
          ),
          initialScale: PhotoViewComputedScale.contained * 0.9,
        );

这个child我们可以根据需求自定义哈,现在在Run下,牟问题啦✌️


ok

你可能感兴趣的:(Flutter 图片查看 photo_view)