|
@@ -1,3 +1,4 @@ |
|
|
|
|
|
import 'dart:async'; |
|
|
import 'dart:io'; |
|
|
import 'dart:io'; |
|
|
import 'package:flutter/material.dart'; |
|
|
import 'package:flutter/material.dart'; |
|
|
import 'package:loading_indicator/loading_indicator.dart'; |
|
|
import 'package:loading_indicator/loading_indicator.dart'; |
|
@@ -12,54 +13,41 @@ class PhotoPreview extends StatefulWidget { |
|
|
int index; |
|
|
int index; |
|
|
String heroTagSuffix; |
|
|
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({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<String> images, this.index = 0, this.heroTagSuffix = ""}) |
|
|
|
|
|
: super(key: key) { |
|
|
|
|
|
|
|
|
PhotoPreview._showPhotoViewByImages({Key key, List<String> images, this.index = 0, this.heroTagSuffix = ""}) : super(key: key) { |
|
|
if (images != null) { |
|
|
if (images != null) { |
|
|
previewImageDatas = List(); |
|
|
previewImageDatas = List(); |
|
|
for (var img in images) { |
|
|
for (var img in images) { |
|
|
previewImageDatas.add(PreviewImageData( |
|
|
|
|
|
previewImageType: PreviewImageType.netUrl, data: img)); |
|
|
|
|
|
|
|
|
previewImageDatas.add(PreviewImageData(previewImageType: PreviewImageType.netUrl, data: img)); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
///显示类型的一些预览 |
|
|
///显示类型的一些预览 |
|
|
static showPhotoPreview( |
|
|
|
|
|
BuildContext context, List<PreviewImageData> previewImageDatas, |
|
|
|
|
|
{int currentIndex = 0, String heroTagSuffix}) { |
|
|
|
|
|
Navigator.of(context).push(new FadeRoute( |
|
|
|
|
|
page: PhotoPreview._showPhotoViewByData( |
|
|
|
|
|
previewImageDatas: previewImageDatas, |
|
|
|
|
|
index: currentIndex, |
|
|
|
|
|
heroTagSuffix: heroTagSuffix, |
|
|
|
|
|
))); |
|
|
|
|
|
|
|
|
static showPhotoPreview(BuildContext context, List<PreviewImageData> previewImageDatas, {int currentIndex = 0, String heroTagSuffix}) { |
|
|
|
|
|
Navigator.push( |
|
|
|
|
|
context, |
|
|
|
|
|
MaterialPageRoute( |
|
|
|
|
|
builder: (_) => PhotoPreview._showPhotoViewByData( |
|
|
|
|
|
previewImageDatas: previewImageDatas, |
|
|
|
|
|
index: currentIndex, |
|
|
|
|
|
heroTagSuffix: heroTagSuffix, |
|
|
|
|
|
))); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
///显示仅仅是一组list<String>类型的图片预览 |
|
|
///显示仅仅是一组list<String>类型的图片预览 |
|
|
static showPhotoPreviewByimages(BuildContext context, List<String> images, |
|
|
|
|
|
{int currentIndex = 0, String heroTagSuffix = ""}) { |
|
|
|
|
|
Navigator.of(context).push(new FadeRoute( |
|
|
|
|
|
page: PhotoPreview._showPhotoViewByImages( |
|
|
|
|
|
images: images, |
|
|
|
|
|
index: currentIndex, |
|
|
|
|
|
heroTagSuffix: heroTagSuffix, |
|
|
|
|
|
))); |
|
|
|
|
|
|
|
|
static showPhotoPreviewByimages(BuildContext context, List<String> images, {int currentIndex = 0, String heroTagSuffix = ""}) { |
|
|
|
|
|
Navigator.push( |
|
|
|
|
|
context, |
|
|
|
|
|
MaterialPageRoute( |
|
|
|
|
|
builder: (_) => PhotoPreview._showPhotoViewByImages( |
|
|
|
|
|
images: images, |
|
|
|
|
|
index: currentIndex, |
|
|
|
|
|
heroTagSuffix: heroTagSuffix, |
|
|
|
|
|
))); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@override |
|
|
@override |
|
@@ -67,24 +55,23 @@ class PhotoPreview extends StatefulWidget { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
class _PhotoPreviewState extends State<PhotoPreview> { |
|
|
class _PhotoPreviewState extends State<PhotoPreview> { |
|
|
PageController pageController; |
|
|
|
|
|
|
|
|
|
|
|
@override |
|
|
@override |
|
|
void initState() { |
|
|
void initState() { |
|
|
pageController = PageController(keepPage: true, initialPage: widget.index); |
|
|
|
|
|
super.initState(); |
|
|
super.initState(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@override |
|
|
@override |
|
|
Widget build(BuildContext context) { |
|
|
Widget build(BuildContext context) { |
|
|
return Scaffold( |
|
|
|
|
|
backgroundColor: Colors.transparent, |
|
|
|
|
|
body: PhotoViewGalleryScreen( |
|
|
|
|
|
|
|
|
return PhotoViewGalleryScreen( |
|
|
images: widget.previewImageDatas, |
|
|
images: widget.previewImageDatas, |
|
|
index: widget.index, |
|
|
index: widget.index, |
|
|
controller: pageController, |
|
|
|
|
|
heroTagSuffix: widget.heroTagSuffix ?? "", |
|
|
heroTagSuffix: widget.heroTagSuffix ?? "", |
|
|
)); |
|
|
|
|
|
|
|
|
); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@override |
|
|
|
|
|
void dispose() { |
|
|
|
|
|
super.dispose(); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@@ -95,8 +82,7 @@ class PreviewImageData { |
|
|
bool isSelect; |
|
|
bool isSelect; |
|
|
String tag; |
|
|
String tag; |
|
|
|
|
|
|
|
|
PreviewImageData( |
|
|
|
|
|
{this.previewImageType, this.data, this.isSelect = false, this.tag}); |
|
|
|
|
|
|
|
|
PreviewImageData({this.previewImageType, this.data, this.isSelect = false, this.tag}); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
///预览类型 |
|
|
///预览类型 |
|
@@ -113,35 +99,38 @@ class PhotoViewGalleryScreen extends StatefulWidget { |
|
|
List<PreviewImageData> images = []; |
|
|
List<PreviewImageData> images = []; |
|
|
int index = 0; |
|
|
int index = 0; |
|
|
String heroTagSuffix; |
|
|
String heroTagSuffix; |
|
|
PageController controller; |
|
|
|
|
|
|
|
|
|
|
|
PhotoViewGalleryScreen( |
|
|
|
|
|
{Key key, |
|
|
|
|
|
@required this.images, |
|
|
|
|
|
this.index, |
|
|
|
|
|
this.controller, |
|
|
|
|
|
this.heroTagSuffix}) |
|
|
|
|
|
: super(key: key) { |
|
|
|
|
|
controller = PageController(initialPage: index); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
PhotoViewGalleryScreen({Key key, @required this.images, this.index, this.heroTagSuffix}) : super(key: key); |
|
|
|
|
|
|
|
|
@override |
|
|
@override |
|
|
_PhotoViewGalleryScreenState createState() => _PhotoViewGalleryScreenState(); |
|
|
_PhotoViewGalleryScreenState createState() => _PhotoViewGalleryScreenState(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
class _PhotoViewGalleryScreenState extends State<PhotoViewGalleryScreen> { |
|
|
|
|
|
|
|
|
class _PhotoViewGalleryScreenState extends State<PhotoViewGalleryScreen> with AutomaticKeepAliveClientMixin { |
|
|
int currentIndex = 0; |
|
|
int currentIndex = 0; |
|
|
|
|
|
PageController pageController; |
|
|
|
|
|
PhotoViewScaleStateController scaleStateController; |
|
|
|
|
|
|
|
|
@override |
|
|
@override |
|
|
void initState() { |
|
|
void initState() { |
|
|
|
|
|
scaleStateController = PhotoViewScaleStateController(); |
|
|
// TODO: implement initState |
|
|
// TODO: implement initState |
|
|
super.initState(); |
|
|
|
|
|
|
|
|
pageController = PageController(initialPage: widget?.index ?? 0); |
|
|
currentIndex = widget.index; |
|
|
currentIndex = widget.index; |
|
|
|
|
|
super.initState(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@override |
|
|
|
|
|
void dispose() { |
|
|
|
|
|
scaleStateController.dispose(); |
|
|
|
|
|
pageController.dispose(); |
|
|
|
|
|
super.dispose(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@override |
|
|
@override |
|
|
Widget build(BuildContext context) { |
|
|
Widget build(BuildContext context) { |
|
|
return Scaffold( |
|
|
return Scaffold( |
|
|
|
|
|
backgroundColor: Colors.black, |
|
|
body: Stack( |
|
|
body: Stack( |
|
|
children: <Widget>[ |
|
|
children: <Widget>[ |
|
|
GestureDetector( |
|
|
GestureDetector( |
|
@@ -149,45 +138,45 @@ class _PhotoViewGalleryScreenState extends State<PhotoViewGalleryScreen> { |
|
|
Navigator.pop(context); |
|
|
Navigator.pop(context); |
|
|
}, |
|
|
}, |
|
|
child: Container( |
|
|
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: <Widget>[ |
|
|
|
|
|
Container( |
|
|
|
|
|
|
|
|
margin: EdgeInsets.all(1), |
|
|
|
|
|
child: PhotoViewGallery.builder( |
|
|
|
|
|
scrollPhysics: const BouncingScrollPhysics(), |
|
|
|
|
|
builder: (BuildContext context, int index) { |
|
|
|
|
|
return PhotoViewGalleryPageOptions( |
|
|
|
|
|
scaleStateController: scaleStateController, |
|
|
|
|
|
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: <Widget>[ |
|
|
|
|
|
Container( |
|
|
width: 48, |
|
|
width: 48, |
|
|
constraints: BoxConstraints(maxWidth: 48,maxHeight: 48), |
|
|
|
|
|
|
|
|
constraints: BoxConstraints(maxWidth: 48, maxHeight: 48), |
|
|
height: 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; |
|
|
|
|
|
}); |
|
|
|
|
|
}, |
|
|
|
|
|
)), |
|
|
|
|
|
|
|
|
child: LoadingIndicator( |
|
|
|
|
|
indicatorType: Indicator.ballSpinFadeLoader, |
|
|
|
|
|
color: Colors.white, |
|
|
|
|
|
)), |
|
|
|
|
|
], |
|
|
|
|
|
); |
|
|
|
|
|
}, |
|
|
|
|
|
backgroundDecoration: BoxDecoration(color: Colors.black), |
|
|
|
|
|
pageController: pageController, |
|
|
|
|
|
enableRotation: true, |
|
|
|
|
|
onPageChanged: (index) { |
|
|
|
|
|
setState(() { |
|
|
|
|
|
currentIndex = index; |
|
|
|
|
|
}); |
|
|
|
|
|
}, |
|
|
|
|
|
), |
|
|
|
|
|
), |
|
|
), |
|
|
), |
|
|
Positioned( |
|
|
Positioned( |
|
|
//图片index显示 |
|
|
//图片index显示 |
|
@@ -195,8 +184,7 @@ class _PhotoViewGalleryScreenState extends State<PhotoViewGalleryScreen> { |
|
|
width: MediaQuery.of(context).size.width, |
|
|
width: MediaQuery.of(context).size.width, |
|
|
child: Container( |
|
|
child: Container( |
|
|
child: Center( |
|
|
child: Center( |
|
|
child: Text("${currentIndex + 1}/${widget.images.length}", |
|
|
|
|
|
style: TextStyle(color: Colors.white, fontSize: 16)), |
|
|
|
|
|
|
|
|
child: Text("${currentIndex + 1}/${widget.images.length}", style: TextStyle(color: Colors.white, fontSize: 16)), |
|
|
), |
|
|
), |
|
|
), |
|
|
), |
|
|
), |
|
|
), |
|
@@ -228,6 +216,10 @@ class _PhotoViewGalleryScreenState extends State<PhotoViewGalleryScreen> { |
|
|
return Image.file(File(item.data)).image; |
|
|
return Image.file(File(item.data)).image; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@override |
|
|
|
|
|
// TODO: implement wantKeepAlive |
|
|
|
|
|
bool get wantKeepAlive => true; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
class FadeRoute extends PageRouteBuilder { |
|
|
class FadeRoute extends PageRouteBuilder { |
|
|