单图片预览
单独写一个页面,作为图片预览的界面:
import 'package:flutter/material.dart';
import 'package:photo_view/photo_view.dart';
class PhotoViewSimpleScreen extends StateleeWidget{
const PhotoViewSimpleScreen({
this.imageProvider,//图片
this.loadingChild,//加载时的widget
this.backgroundDecoration,//背景修饰
this.minScale,//最大缩放倍数
this.maxScale,//最小缩放倍数
this.heroTag,//hero动画tagid
});
final ImageProvider imageProvider;
final Widget loadingChild;
final Decoration backgroundDecoration;
final dynamic minScale;
final dynamic maxScale;
final String heroTag;
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
constraints: BoxConstraints.expand(
height: MediaQuery.of(context).size.height,
),
child: Stack(
children: <Widget>[
Positioned(
top: 0,
left: 0,
bottom: 0,
right: 0,
child: PhotoView(
imageProvider: imageProvider,
loadingChild: loadingChild,
backgroundDecoration: backgroundDecoration,
minScale: minScale,
maxScale: maxScale,
heroAttributes: PhotoViewHeroAttributes(tag: heroTag),
enableRotation: true,
),
),
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();
},
),
)
],
),
),
);
}
}
给你展示缩图的地方加上点击事件,打开写好的预览界面:
onTap: (){
Navigator.of(context).push(new FadeRoute(page: PhotoViewSimpleScreen(
imageProvider:NetworkImage(img),
heroTag: 'simple',
)));
},
效果如上面gif的第一个效果。
多图片预览
再单独写一个页面,作为多图片预览的界面:
import 'package:flutter/material.dart';
import 'package:photo_view/photo_view.dart';
import 'package:photo_view/photo_view_gallery.dart';
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<PhotoViewGalleryScreen> {
int currentIndex=0;
@override
void initState() {
// TODO: implement initState
super.initState();
currentIndex=widget.index;
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: <Widget>[
Positioned(
top: 0,
left: 0,
bottom: 0,
right: 0,
child: Container(
child: PhotoViewGallery.builder(
scrollPhysics: const BouncingScrollPhysics(),
builder: (BuildContext context, int index) {
return PhotoViewGalleryPageOptions(
imageProvider: NetworkImage(widget.images[index]),
heroAttributes: widget.heroTag.isNotEmpty?PhotoViewHeroAttributes(tag: widget.heroTag):null,
);
},
itemCount: widget.images.length,
loadingChild: Container(),
backgroundDecoration: null,
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: 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();
},
),
),
],
),
);
}
}
给你展示缩图的地方加上点击事件,打开写好的预览界面:
onTap: (){
//FadeRoute是自定义的切换过度动画(渐隐渐现) 如果不需要 可以使用默认的MaterialPageRoute
Navigator.of(context).push(new FadeRoute(page: PhotoViewGalleryScreen(
images:imgs,//传入图片list
index: index,//传入当前点击的图片的index
heroTag: img,//传入当前点击的图片的hero tag (可选)
)));
},
FadeRoute的源码:
class FadeRoute extends PageRouteBuilder {
final Widget page;
FadeRoute({this.page}): super(
pageBuilder: (
BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation,
) =>page,transitionsBuilder: (
BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation,
Widget child,
) =>FadeTransition(
opacity: animation,
child: child,
),
);
}
效果如上面gif的第二个效果。
从上面的代码可以看出,不管是单图还是多图预览,预览界面的布局都是完全自己定义的,虽然不是拿来即用,但是可定制度非常高,非常合适改造成自己的项目风格。
常用的参数
PhotoView(
imageProvider: imageProvider, //要显示的图片 AssetImage 或者 NetworkImage
loadingChild: loadingChild,//loading时显示的widget
backgroundDecoration: backgroundDecoration,//背景修饰
minScale: minScale,//最大缩放倍数
maxScale: maxScale,//最小缩放倍数
heroAttributes: PhotoViewHeroAttributes(tag: heroTag),//hero动画tag 不设置或null为不启用hero动画
enableRotation: true,//是否允许旋转
.....
)