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…