flutter好用的輪子推薦四-可定製的圖片預覽查看器photo_view

前言

Flutter是谷歌的移動UI框架,能夠快速在iOS和Android上構建高質量的原生用戶界面。html

IT界著名的尼古拉斯·高爾包曾說:輪子是IT進步的階梯!熱門的框架千篇一概,好用輪子萬里挑一!Flutter做爲這兩年開始崛起的跨平臺開發框架,其第三方生態相比其餘成熟框架還略有不足,但輪子的數量也已經不少了。本系列文章挑選平常app開發經常使用的輪子分享出來,給你們提升搬磚效率,同時也但願flutter的生態愈來愈完善,輪子愈來愈多。git

本系列文章準備了超過50個輪子推薦,工做緣由,儘可能每1-2天出一篇文章。github

tip:本系列文章合適已有部分flutter基礎的開發者,入門請戳:flutter官網app

正文

輪子

  • 輪子名稱: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"),
        )
    );
}
複製代碼

初步的效果是這樣的: 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();
                            },
                        ),
                    )
                ],
            ),
        ),
        );
    }

}

複製代碼

給你展現縮圖的地方加上點擊事件,打開寫好的預覽界面:動畫

onTap: (){
    Navigator.of(context).push(new FadeRoute(page: PhotoViewSimpleScreen(
        imageProvider:NetworkImage(img),
        heroTag: 'simple',
    )));
},
複製代碼

效果如上面gif的第一個效果。ui

多圖片預覽

再單獨寫一個頁面,做爲多圖片預覽的界面:this

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…

結尾

相關文章
相關標籤/搜索