import 'dart:io'; import 'package:flutter/material.dart'; import 'package:loading_indicator/loading_indicator.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; String heroTagSuffix; PhotoPreview( {Key key, this.previewImageDatas, this.index = 0, this.heroTagSuffix = ""}) : super(key: key); PhotoPreview._showPhotoViewByData( {Key key, this.previewImageDatas, this.index = 0, this.heroTagSuffix = ""}) : super(key: key) { } PhotoPreview._showPhotoViewByImages( {Key key, List images, this.index = 0, this.heroTagSuffix = ""}) : 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, String heroTagSuffix}) { Navigator.of(context).push(new FadeRoute( page: PhotoPreview._showPhotoViewByData( previewImageDatas: previewImageDatas, index: currentIndex, heroTagSuffix: heroTagSuffix, ))); } ///显示仅仅是一组list类型的图片预览 static showPhotoPreviewByimages(BuildContext context, List images, {int currentIndex = 0, String heroTagSuffix = ""}) { Navigator.of(context).push(new FadeRoute( page: PhotoPreview._showPhotoViewByImages( images: images, index: currentIndex, heroTagSuffix: heroTagSuffix, ))); } @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, heroTagSuffix: widget.heroTagSuffix ?? "", )); } } ///图片预览数据 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 heroTagSuffix; PageController controller; PhotoViewGalleryScreen( {Key key, @required this.images, this.index, this.controller, this.heroTagSuffix}) : 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.heroTagSuffix.isNotEmpty ? PhotoViewHeroAttributes( tag: (widget.images[index].data ?? "") + widget.heroTagSuffix) : null, ); }, itemCount: widget.images.length, loadFailedChild: Container( child: Text("加载失败"), ), loadingBuilder: (context,event){ return Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Container( width: 48, constraints: BoxConstraints(maxWidth: 48,maxHeight: 48), height: 48, child: LoadingIndicator(indicatorType: Indicator.ballSpinFadeLoader,color: Colors.white,) ), ], ); }, 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, ) => FadeTransition( opacity: animation, child: child, ), ); }