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

前言

Flutter是谷歌的移动UI框架,可以快速在iOS和Android上构建高质量的原生用户界面。

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"),

)

);

}

初步的效果是这样的:

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,//是否允许旋转

.....

)

结尾

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/311247.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

pandas的apply函数解析

apply函数 apply函数是pandas里面所有函数中自由度最高的函数。该函数如下: DataFrame.apply(func, axis0, broadcastFalse, rawFalse, reduceNone, args(), **kwds)该函数最有用的是第一个参数,这个参数是函数,相当于C/C的函数指针。 这个…

如何编写高性能的C#代码(一)

原文来自互联网,由长沙DotNET技术社区编译。如译文侵犯您的署名权或版权,请联系小编,小编将在24小时内删除。作者介绍:史蒂夫戈登(Steve Gordon)是Microsoft MVP,Pluralsight的作者,…

hdu 2069 Coin Change(改)-dp

有5种面值的硬币&#xff0c;即1分&#xff0c;5分&#xff0c;10分&#xff0c;25分&#xff0c;50分。输入一个钱数s&#xff0c;输出组合方案的数量。 s<250&#xff0c;硬币数量不限。 代码如下&#xff1a; #include <iostream> using namespace std; const i…

博途plc连接电脑_PLC报错,电脑连接不了PLC

需要进行S7-1200的固件版本更新。更新CPU的固件具体步骤如下&#xff1a;第一步&#xff1a;使用电脑通过读卡器清除存储卡中内容。注意&#xff1a;不要格式化存储卡&#xff01;第二步&#xff1a; 从西门子官方网站下载最新版本的固件文件。下载并解压缩&#xff0c;用户可以…

SQL(八)- python执行SQL语句

PyMySQL python 3.x版本中连接MySQL数据库使用第三方库pysqhl&#xff1b;python 2.x版本中连接MySQL数据库使用第三方库mysqldb&#xff1b; 连接PyMySQL 安装&#xff1a; pip install pymysql连接 (1)用python连接mysql&#xff0c;执行sql语句&#xff0c;返回mysql当…

从Java转向.NET/C#,Are You OK?

最近由于项目变动&#xff0c;需要用.NET/C#做开发&#xff0c;经过一段时间的学习和培训&#xff0c;对这个技术栈有了一定的理解。大家可能都知道Java和.NET/C#很像&#xff0c;这里粗略的把两者做一个对比&#xff0c;希望对感兴趣的童鞋有所帮助。如果现在有人问我&#xf…

如何看待潘石屹搞python_潘石屹考了99分的Python,到底是一种什么存在?

去年&#xff0c;当地产大佬潘石屹要把学习Python作为生日礼物送给自己的时候&#xff0c;微博上还多是一阵调侃之声。可能正是印证了Python程序员们常常挂在嘴边的“人生苦短&#xff0c;就学Python”的口头禅&#xff0c;时年56岁的小潘同学要再一次抓住“青春”的尾巴吧。为…

python机器学习、数据分析常用第三方库(实时更新)

常用镜像源&#xff1a; 清华&#xff1a;https://pypi.tuna.tsinghua.edu.cn/simple 阿里&#xff1a;http://mirrors.aliyun.com/pypi/simple/ 豆瓣&#xff1a;http://pypi.douban.com/simple/ 华中理工大学&#xff1a;http://pypi.hustunique.com/ 山东理工大学&#xff…

树的节点值之和

题目背景 墨家家主有棵树。 题目描述 给定一个保存树节点信息的数据结构&#xff0c;它包含了树节点唯一的 id &#xff0c;树节点值 和 直系子节点的 id 。 比如&#xff0c;树节点1是树节点2的父节点&#xff0c;树节点2是树节点3的父节点。他们相应的树节点值为 9 , 4 , …

.NET Core开发实战(第21课:中间件:掌控请求处理过程的关键)--学习笔记(上)...

21 | 中间件&#xff1a;掌控请求处理过程的关键这一节讲解一下如何通过中间件来管理请求处理过程中间件工作原理next 表示后面有一个委托&#xff0c;每一层每一层套下去可以在任意的中间件来决定在后面的中间件之前执行什么&#xff0c;或者说在所有中间件执行完之后执行什么…

angularjsl路由_AngularJs ng-route路由详解

本篇基于ng-route来讲下angular中的路由&#xff0c;路由功能主要是 $routeProvider服务 与 ng-view 实现。ng-view的实现原理&#xff0c;是根据路由的切换&#xff0c;动态编译html模板——$compile(html)(scope)。前提首先需要在页面引入angular和angular-route&#xff0c;…

pandas中Series的map函数详解

Series的map函数 Series的map方法可以接受一个函数或含有映射关系的字典型对象。使用map是一种实现元素级转换以及其他数据清理工作的便捷方式。DataFrame中对应的是applymap()函数&#xff0c;当然DataFrame还有apply()函数 1.字典映射 例如&#xff0c;对数据的某个字段进…

简单的二叉树创建与遍历

编一个程序&#xff0c;读入用户输入的一串先序遍历字符串&#xff0c;根据此字符串建立一个二叉树&#xff08;以指针方式存储&#xff09;。 例如如下的先序遍历字符串&#xff1a; ABC##DE#G##F### 其中“#”表示的是空格&#xff0c;空格字符代表空树。建立起此二叉树以后&…

tof摄像头手势识别_一种基于TOF手势识别的控制系统的制作方法

本发明属于汽车零配件技术领域&#xff0c;尤其是一种基于TOF手势识别的控制系统。背景技术&#xff1a;随着触摸屏技术的不断推广&#xff0c;用户已经适应并逐渐熟悉了与机器的互动。现在&#xff0c;人机互动技术已迈上了更高的台阶&#xff0c;进入了手势识别时代。随着手势…

疫情期间,千万级系统宕机N次,老板撂下狠话:没法把性提升10倍,全员解雇!...

性能调优整体思路作为一名团队技术核心&#xff0c;如何让系统跑得通、跑得稳、跑得快是必然会面对的场景。性能分析是一个大课题&#xff0c;不同的架构、不同的应用场景、不同的程序语言分析的方法若有差异&#xff0c;抽象一下大致分为两类&#xff1a;自底向上&#xff1a;…

Pandas - 查看DataFrame信息

数据表信息查看 1、维度查看&#xff1a; df.shape2、数据表基本信息&#xff08;维度、列名称、数据格式、所占空间等&#xff09;&#xff1a; df.info()3、每一列数据的格式&#xff1a; df.dtypes4、某一列格式&#xff1a; df[B].dtype5、空值&#xff1a; df.isnul…

hdu2602 Bone Collector-01背包问题

Problem Description Many years ago , in Teddy’s hometown there was a man who was called “Bone Collector”. This man like to collect varies of bones , such as dog’s , cow’s , also he went to the grave … The bone collector had a big bag with a volume of…

对比Java和.NET多线程编程

这篇文章以对比的方式总结Java和.NET多线程编程。基本概念多线程&#xff1a;很多开发语言都提供多线程编程支持&#xff0c;比如Java&#xff0c;C#。并发&#xff08;concurrent&#xff09;&#xff1a;即使对于单核CPU&#xff0c;我们也会采用多线程等技术提高service的并…

Anaconda创建python虚拟环境

在创建虚拟环境之前首先我们需要打开命令终端&#xff1a;Win R 输入cmd 或者直接打开Anaconda Prompt&#xff08;Anaconda&#xff09; pycharm下载历史版本地址&#xff1a;https://www.jetbrains.com/pycharm/download/other.html Anaconda下载历史版本地址&#xff1a;ht…

vue2实践揭秘pdf_《Vue2.0 实践揭秘》终于出版啦!

不知不觉间在园子开博都两年多了&#xff0c;最近一些园友问最近去哪了为何都没有新的文章了。最近确实发生了很多的事&#xff0c;一是忙工作二就是忙着写书。这还得多些园子的小编&#xff0c;自两年前发表的“架构师修炼”系列的文章后被出版社相出让我将这个主题写成书&…