import 'dart:io'; import 'package:flutter/material.dart'; import 'package:photo_view/photo_view.dart'; import 'package:photo_view/photo_view_gallery.dart'; import 'package:zhiying_comm/zhiying_comm.dart'; ///图片预览控件 class PhotoPreview extends StatefulWidget { List previewImageDatas; int index; PhotoPreview({Key key, this.previewImageDatas, this.index = 0}) : super(key: key); PhotoPreview._showPhotoViewByData( {Key key, this.previewImageDatas, this.index}) : super(key: key); PhotoPreview._showPhotoViewByImages( {Key key, List images, this.index}) : super(key: key) { if (images != null) { previewImageDatas = List(); for (var img in images) { previewImageDatas.add(PreviewImageData( previewImageType: PreviewImageType.netUrl, data: img)); } } } ///显示类型的一些预览 static showPhotoPreview( BuildContext context, List previewImageDatas, {int currentIndex = 0}) { Navigator.of(context).push(new FadeRoute( page: PhotoPreview._showPhotoViewByData( previewImageDatas: previewImageDatas, index: currentIndex, ))); } ///显示仅仅是一组list类型的图片预览 static showPhotoPreviewByimages(BuildContext context, List images, {int currentIndex = 0}) { Navigator.of(context).push(new FadeRoute( page: PhotoPreview._showPhotoViewByImages( images: images, index: currentIndex, ))); } @override _PhotoPreviewState createState() => _PhotoPreviewState(); } class _PhotoPreviewState extends State { PageController pageController; @override void initState() { pageController = PageController(keepPage: true, initialPage: widget.index); super.initState(); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.transparent, body: PhotoViewGalleryScreen( images: widget.previewImageDatas, index: widget.index, controller: pageController, heroTag: "", )); } } ///图片预览数据 class PreviewImageData { PreviewImageType previewImageType; String data; bool isSelect; String tag; PreviewImageData( {this.previewImageType, this.data, this.isSelect = false, this.tag}); } ///预览类型 enum PreviewImageType { netUrl, ///网络图片 filePath ///本地文件路径 } class PhotoViewGalleryScreen extends StatefulWidget { List images = []; int index = 0; String heroTag; PageController controller; PhotoViewGalleryScreen( {Key key, @required this.images, this.index, this.controller, this.heroTag}) : super(key: key) { controller = PageController(initialPage: index); } @override _PhotoViewGalleryScreenState createState() => _PhotoViewGalleryScreenState(); } class _PhotoViewGalleryScreenState extends State { int currentIndex = 0; @override void initState() { // TODO: implement initState super.initState(); currentIndex = widget.index; } @override Widget build(BuildContext context) { return Scaffold( body: Stack( children: [ GestureDetector( onTap: () { Navigator.pop(context); }, child: Container( color: Colors.black, child: PhotoViewGallery.builder( scrollPhysics: const BouncingScrollPhysics(), builder: (BuildContext context, int index) { return PhotoViewGalleryPageOptions( imageProvider: _buildPage(context, index), heroAttributes: widget.heroTag.isNotEmpty ? PhotoViewHeroAttributes(tag: widget.heroTag) : null, ); }, itemCount: widget.images.length, loadFailedChild: Container( child: Text("加载失败"), ), backgroundDecoration: BoxDecoration(color: Colors.black), pageController: widget.controller, enableRotation: true, onPageChanged: (index) { setState(() { currentIndex = index; }); }, )), ), Positioned( //图片index显示 top: MediaQuery.of(context).padding.top + 15, width: MediaQuery.of(context).size.width, child: Container( child: Center( child: Text("${currentIndex + 1}/${widget.images.length}", style: TextStyle(color: Colors.white, fontSize: 16)), ), ), ), Positioned( //右上角关闭按钮 right: 10, top: MediaQuery.of(context).padding.top, child: IconButton( icon: Icon( Icons.close, size: 30, color: Colors.white, ), onPressed: () { Navigator.of(context).pop(); }, ), ), ], ), ); } ImageProvider _buildPage(BuildContext context, int index) { var item = widget.images[index]; if (item.previewImageType == PreviewImageType.netUrl) { return CachedNetworkImageProvider(item.data); } else if (item.previewImageType == PreviewImageType.filePath) { return Image.file(File(item.data)).image; } } } class FadeRoute extends PageRouteBuilder { final Widget page; FadeRoute({this.page}) : super( pageBuilder: ( BuildContext context, Animation animation, Animation secondaryAnimation, ) => page, transitionsBuilder: ( BuildContext context, Animation animation, Animation secondaryAnimation, Widget child, ) => ScaleTransition( scale: animation, child: FadeTransition( opacity: animation, child: child, ), ), ); }