flutter好用的轮子推荐四-可定制的图片预览查看器photo_view

前言 Flutter是谷歌的移动UI框架,可以快速在iOS和Android上构建高质量的原生用户界面。
【flutter好用的轮子推荐四-可定制的图片预览查看器photo_view】IT界著名的尼古拉斯·高尔包曾说:轮子是IT进步的阶梯!热门的框架千篇一律,好用轮子万里挑一!Flutter作为这两年开始崛起的跨平台开发框架,其第三方生态相比其他成熟框架还略有不足,但轮子的数量也已经很多了。本系列文章挑选日常app开发常用的轮子分享出来,给大家提高搬砖效率,同时也希望flutter的生态越来越完善,轮子越来越多。
本系列文章准备了超过50个轮子推荐,工作原因,尽量每1-2天出一篇文章。
tip:本系列文章合适已有部分flutter基础的开发者,入门请戳: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"), ) ); }

初步的效果是这样的:

flutter好用的轮子推荐四-可定制的图片预览查看器photo_view
文章图片
image
可以放大查看,但这是一个已经打开预览界面的样子,日常使用我们需要从缩略图点击打开预览页面,就像上面效果图那样,所以我们需要自己写一个单独的预览界面,然后从缩略图点击打开。
单图片预览 单独写一个页面,作为图片预览的界面:
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: [ 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 { int currentIndex=0; @override void initState() { // TODO: implement initState super.initState(); currentIndex=widget.index; }@override Widget build(BuildContext context) { return Scaffold( body: Stack( children: [ 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 animation, Animation secondaryAnimation, ) =>page,transitionsBuilder: ( BuildContext context, Animation animation, Animation 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
结尾
  • 轮子仓库地址:https://pub.flutter-io.cn/packages/photo_view
  • 系列演示demo源码:https://github.com/826327700/flutter_plugins_demo

    推荐阅读