「Flutter/画像/画像viewer」の版間の差分
提供: 初心者エンジニアの簡易メモ
(→サンプル) |
(→画像アニメーション(hero)) |
||
| (同じ利用者による、間の6版が非表示) | |||
| 行60: | 行60: | ||
); | ); | ||
</pre> | </pre> | ||
| + | |||
参考:https://resocoder.com/2019/05/04/flutter-photo-view-gallery-resize-rotate-image-carousel/ | 参考: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)
),
