Flutter是谷歌的移动UI框架,能够快速在iOS和Android上构建高质量的原生用户界面。html
IT界著名的尼古拉斯·高尔包曾说:轮子是IT进步的阶梯!热门的框架千篇一概,好用轮子万里挑一!Flutter做为这两年开始崛起的跨平台开发框架,其第三方生态相比其余成熟框架还略有不足,但轮子的数量也已经不少了。本系列文章挑选平常app开发经常使用的轮子分享出来,给你们提升搬砖效率,同时也但愿flutter的生态愈来愈完善,轮子愈来愈多。git
本系列文章准备了超过50个轮子推荐,工做缘由,尽可能每1-2天出一篇文章。github
tip:本系列文章合适已有部分flutter基础的开发者,入门请戳:flutter官网markdown
dependencies: photo_view: ^0.7.0 复制代码
import 'package:photo_view/photo_view.dart'; 复制代码
默认最简单的使用方式:app
@override Widget build(BuildContext context) { return Container( child: PhotoView( imageProvider: AssetImage("assets/large-image.jpg"), ) ); } 复制代码
初步的效果是这样的: 框架
单独写一个页面,做为图片预览的界面:ide
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(); }, ), ) ], ), ), ); } } 复制代码
给你展现缩图的地方加上点击事件,打开写好的预览界面:oop
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,//是否容许旋转 ..... ) 复制代码
查看全部的参数:pub.flutter-io.cn/documentati…