「Flutter/画像/画像viewer」の版間の差分
提供: 初心者エンジニアの簡易メモ
(→サンプル) |
(→画像アニメーション(hero)) |
||
(同じ利用者による、間の8版が非表示) | |||
行10: | 行10: | ||
==サンプル== | ==サンプル== | ||
− | ローカル画像 | + | ===ローカル画像=== |
<pre> | <pre> | ||
import 'package:photo_view/photo_view.dart'; | import 'package:photo_view/photo_view.dart'; | ||
行20: | 行20: | ||
</pre> | </pre> | ||
− | ネット画像 | + | ===ネット画像=== |
<pre> | <pre> | ||
import 'package:photo_view/photo_view.dart'; | import 'package:photo_view/photo_view.dart'; | ||
行26: | 行26: | ||
PhotoView photoView = PhotoView( | PhotoView photoView = PhotoView( | ||
imageProvider: NetworkImage(imageUrl), | imageProvider: NetworkImage(imageUrl), | ||
+ | // imageProvider: NetworkImage("http://wiki.nonip.net/skins/Vector/images/share/d.png"), | ||
); | ); | ||
} | } | ||
行31: | 行32: | ||
imageUrlにはnullを一度でも入れると表示されなくなる。asyncを使ってる場合は注意。値渡しはprefを経由するなどではなく、Navigatorからそのまま値を渡したほうが良いかも。 | imageUrlにはnullを一度でも入れると表示されなくなる。asyncを使ってる場合は注意。値渡しはprefを経由するなどではなく、Navigatorからそのまま値を渡したほうが良いかも。 | ||
+ | |||
+ | ===次前へ移動できるviewer=== | ||
+ | <pre> | ||
+ | PhotoViewGallery photoViewGallery = PhotoViewGallery.builder( | ||
+ | scrollPhysics: const BouncingScrollPhysics(), | ||
+ | builder: (BuildContext context, int index) { | ||
+ | NetworkImage networkImage = NetworkImage(imgs[index].url); | ||
+ | FadeInImage image = FadeInImage.assetNetwork( | ||
+ | placeholder: 'assets/loading.gif', | ||
+ | image: imgs[index].url, | ||
+ | fit: BoxFit.cover, | ||
+ | ); | ||
+ | return PhotoViewGalleryPageOptions( | ||
+ | imageProvider: networkImage, | ||
+ | initialScale: PhotoViewComputedScale.contained, | ||
+ | minScale: PhotoViewComputedScale.contained * 0.7, | ||
+ | maxScale: PhotoViewComputedScale.covered * 2, | ||
+ | ); | ||
+ | }, | ||
+ | itemCount: imgs.length, | ||
+ | backgroundDecoration: BoxDecoration( | ||
+ | color: Theme.of(context).canvasColor, | ||
+ | ), | ||
+ | loadingChild: Center( | ||
+ | child: CircularProgressIndicator(), | ||
+ | ), | ||
+ | ); | ||
+ | </pre> | ||
+ | |||
+ | 参考:https://resocoder.com/2019/05/04/flutter-photo-view-gallery-resize-rotate-image-carousel/ | ||
+ | |||
+ | 参考:https://www.cnblogs.com/gggggggxin/p/11195401.html | ||
+ | |||
+ | ===一覧から次前へ移動できるviewerへ=== | ||
+ | <pre> | ||
+ | class ImageViewerPage extends StatefulWidget { | ||
+ | final String title; | ||
+ | final int initialIndex; | ||
+ | PageController pageController; | ||
+ | List<Img> imgs = []; | ||
+ | ImageViewerPage({Key key, this.title, this.imgs, this.initialIndex}) : super(key: key) { | ||
+ | pageController = PageController(initialPage: initialIndex); | ||
+ | } | ||
+ | @override | ||
+ | _ImageViewerPageState createState() => _ImageViewerPageState(); | ||
+ | } | ||
+ | |||
+ | class _ImageViewerPageState extends State<ImageViewerPage> { | ||
+ | int currentIndex; | ||
+ | bool initFlag = true; | ||
+ | @override | ||
+ | void initState() { | ||
+ | super.initState(); | ||
+ | setState(() { | ||
+ | currentIndex = widget.initialIndex; | ||
+ | }); | ||
+ | } | ||
+ | void onPageChanged(int index) { | ||
+ | setState(() { | ||
+ | currentIndex = index; | ||
+ | }); | ||
+ | } | ||
+ | @override | ||
+ | Widget build(BuildContext context) { | ||
+ | PhotoViewGallery photoViewGallery = PhotoViewGallery.builder( | ||
+ | scrollPhysics: const BouncingScrollPhysics(), | ||
+ | builder: (BuildContext context, int index) { | ||
+ | NetworkImage networkImage = NetworkImage(widget.imgs[index].url); | ||
+ | return PhotoViewGalleryPageOptions( | ||
+ | imageProvider: networkImage, | ||
+ | initialScale: PhotoViewComputedScale.contained, | ||
+ | minScale: PhotoViewComputedScale.contained * 0.7, | ||
+ | maxScale: PhotoViewComputedScale.covered * 2, | ||
+ | heroAttributes: PhotoViewHeroAttributes(tag: widget.imgs[index].url), | ||
+ | ); | ||
+ | }, | ||
+ | itemCount: widget.imgs.length, | ||
+ | onPageChanged: onPageChanged, | ||
+ | pageController: widget.pageController, | ||
+ | backgroundDecoration: BoxDecoration( | ||
+ | color: Theme.of(context).canvasColor, | ||
+ | ), | ||
+ | loadingChild: Center( | ||
+ | child: CircularProgressIndicator(), | ||
+ | ), | ||
+ | ); | ||
+ | return Scaffold( | ||
+ | appBar: AppBar( | ||
+ | backgroundColor: Colors.blue.withOpacity(0.3), | ||
+ | elevation: 0.0, | ||
+ | title: Text("画像", | ||
+ | style: TextStyle( | ||
+ | fontSize: 16, | ||
+ | locale: Locale("ja", "JP") | ||
+ | ) | ||
+ | ), | ||
+ | ), | ||
+ | extendBodyBehindAppBar: true, | ||
+ | body: photoViewGallery | ||
+ | ); | ||
+ | } | ||
+ | } | ||
+ | </pre> | ||
+ | imgsにはnullを一度でも入れると初回の一枚目が開いてしまう。asyncを使って取得するのではなく、Navigatorからそのまま値を渡したほうが良い。 | ||
+ | |||
+ | ==画像アニメーション(hero)== | ||
+ | heroを使うには、遷移先、遷移元のimageを以下のようにする。tagの文字列を一致させる。 | ||
+ | |||
+ | photoViewでは | ||
+ | <pre> | ||
+ | PhotoViewGalleryPageOptions( | ||
+ | heroAttributes: PhotoViewHeroAttributes(tag: url), | ||
+ | ) | ||
+ | </pre> | ||
+ | 遷移先、遷移元 | ||
+ | <pre> | ||
+ | Hero( | ||
+ | tag: url, | ||
+ | child: Image.network(url) | ||
+ | ), | ||
+ | </pre> |
2020年1月24日 (金) 23:51時点における最新版
目次
インストール
pubspec.yaml
dependencies: photo_view: ^0.9.1
公式
https://pub.dev/packages/photo_view
サンプル
ローカル画像
import 'package:photo_view/photo_view.dart'; PhotoView photoView = PhotoView( imageProvider: AssetImage("assets/image1.jpg"), minScale: PhotoViewComputedScale.contained * 1.0, maxScale: 2.0, );
ネット画像
import 'package:photo_view/photo_view.dart'; if (imageUrl != null) { PhotoView photoView = PhotoView( imageProvider: NetworkImage(imageUrl), // imageProvider: NetworkImage("http://wiki.nonip.net/skins/Vector/images/share/d.png"), ); }
imageUrlにはnullを一度でも入れると表示されなくなる。asyncを使ってる場合は注意。値渡しはprefを経由するなどではなく、Navigatorからそのまま値を渡したほうが良いかも。
次前へ移動できるviewer
PhotoViewGallery photoViewGallery = PhotoViewGallery.builder( scrollPhysics: const BouncingScrollPhysics(), builder: (BuildContext context, int index) { NetworkImage networkImage = NetworkImage(imgs[index].url); FadeInImage image = FadeInImage.assetNetwork( placeholder: 'assets/loading.gif', image: imgs[index].url, fit: BoxFit.cover, ); return PhotoViewGalleryPageOptions( imageProvider: networkImage, initialScale: PhotoViewComputedScale.contained, minScale: PhotoViewComputedScale.contained * 0.7, maxScale: PhotoViewComputedScale.covered * 2, ); }, itemCount: imgs.length, backgroundDecoration: BoxDecoration( color: Theme.of(context).canvasColor, ), loadingChild: Center( child: CircularProgressIndicator(), ), );
参考:https://resocoder.com/2019/05/04/flutter-photo-view-gallery-resize-rotate-image-carousel/
参考:https://www.cnblogs.com/gggggggxin/p/11195401.html
一覧から次前へ移動できるviewerへ
class ImageViewerPage extends StatefulWidget { final String title; final int initialIndex; PageController pageController; List<Img> imgs = []; ImageViewerPage({Key key, this.title, this.imgs, this.initialIndex}) : super(key: key) { pageController = PageController(initialPage: initialIndex); } @override _ImageViewerPageState createState() => _ImageViewerPageState(); } class _ImageViewerPageState extends State<ImageViewerPage> { int currentIndex; bool initFlag = true; @override void initState() { super.initState(); setState(() { currentIndex = widget.initialIndex; }); } void onPageChanged(int index) { setState(() { currentIndex = index; }); } @override Widget build(BuildContext context) { PhotoViewGallery photoViewGallery = PhotoViewGallery.builder( scrollPhysics: const BouncingScrollPhysics(), builder: (BuildContext context, int index) { NetworkImage networkImage = NetworkImage(widget.imgs[index].url); return PhotoViewGalleryPageOptions( imageProvider: networkImage, initialScale: PhotoViewComputedScale.contained, minScale: PhotoViewComputedScale.contained * 0.7, maxScale: PhotoViewComputedScale.covered * 2, heroAttributes: PhotoViewHeroAttributes(tag: widget.imgs[index].url), ); }, itemCount: widget.imgs.length, onPageChanged: onPageChanged, pageController: widget.pageController, backgroundDecoration: BoxDecoration( color: Theme.of(context).canvasColor, ), loadingChild: Center( child: CircularProgressIndicator(), ), ); return Scaffold( appBar: AppBar( backgroundColor: Colors.blue.withOpacity(0.3), elevation: 0.0, title: Text("画像", style: TextStyle( fontSize: 16, locale: Locale("ja", "JP") ) ), ), extendBodyBehindAppBar: true, body: photoViewGallery ); } }
imgsにはnullを一度でも入れると初回の一枚目が開いてしまう。asyncを使って取得するのではなく、Navigatorからそのまま値を渡したほうが良い。
画像アニメーション(hero)
heroを使うには、遷移先、遷移元のimageを以下のようにする。tagの文字列を一致させる。
photoViewでは
PhotoViewGalleryPageOptions( heroAttributes: PhotoViewHeroAttributes(tag: url), )
遷移先、遷移元
Hero( tag: url, child: Image.network(url) ),