美文网首页Flutter圈子FlutterFlutter中文社区
flutter好用的轮子推荐四-可定制的图片预览查看器photo

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

作者: IT小孢子 | 来源:发表于2019-10-29 08:55 被阅读0次

    前言

    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: <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

    结尾

    相关文章

      网友评论

        本文标题:flutter好用的轮子推荐四-可定制的图片预览查看器photo

        本文链接:https://www.haomeiwen.com/subject/uydivctx.html