前言
Flutter是谷歌的移動UI框架吏奸,可以快速在iOS和Android上構建高質量的原生用戶界面米者。
IT界著名的尼古拉斯·高爾包曾說:輪子是IT進步的階梯花颗!熱門的框架千篇一律大刊,好用輪子萬里挑一淀弹!Flutter作為這兩年開始崛起的跨平臺開發(fā)框架夫壁,其第三方生態(tài)相比其他成熟框架還略有不足拾枣,但輪子的數量也已經很多了。本系列文章挑選日常app開發(fā)常用的輪子分享出來掌唾,給大家提高搬磚效率放前,同時也希望flutter的生態(tài)越來越完善,輪子越來越多糯彬。
本系列文章準備了超過50個輪子推薦凭语,工作原因,盡量每1-2天出一篇文章撩扒。
tip:本系列文章合適已有部分flutter基礎的開發(fā)者似扔,入門請戳:flutter官網
正文
輪子
- 輪子名稱:photo_view
- 輪子概述:可定制的圖片預覽查看器:photo_view.
- 輪子作者:caraujo.me
- 推薦指數:★★★★★
- 常用指數:★★★★★
-
效果預覽:
效果圖
安裝
dependencies:
photo_view: ^0.7.0
import 'package:photo_view/photo_view.dart';
使用
默認最簡單的使用方式:
@override
Widget build(BuildContext context) {
return Container(
child: PhotoView(
imageProvider: AssetImage("assets/large-image.jpg"),
)
);
}
初步的效果是這樣的:
可以放大查看,但這是一個已經打開預覽界面的樣子搓谆,日常使用我們需要從縮略圖點擊打開預覽頁面炒辉,就像上面效果圖那樣,所以我們需要自己寫一個單獨的預覽界面泉手,然后從縮略圖點擊打開黔寇。
單圖片預覽
單獨寫一個頁面,作為圖片預覽的界面:
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,//是否允許旋轉
.....
)
查看所有的參數:https://pub.flutter-io.cn/documentation/photo_view/latest/photo_view/PhotoView-class.html