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

前言

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

初步的效果是這樣的:


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

結尾

?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市昆淡,隨后出現的幾起案子锰瘸,更是在濱河造成了極大的恐慌,老刑警劉巖瘪撇,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件获茬,死亡現場離奇詭異,居然都是意外死亡倔既,警方通過查閱死者的電腦和手機恕曲,發(fā)現死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來渤涌,“玉大人佩谣,你說我怎么就攤上這事∈蹬睿” “怎么了茸俭?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長安皱。 經常有香客問我调鬓,道長,這世上最難降的妖魔是什么酌伊? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任腾窝,我火速辦了婚禮,結果婚禮上居砖,老公的妹妹穿的比我還像新娘虹脯。我一直安慰自己,他們只是感情好奏候,可當我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布循集。 她就那樣靜靜地躺著,像睡著了一般蔗草。 火紅的嫁衣襯著肌膚如雪咒彤。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天蕉世,我揣著相機與錄音蔼紧,去河邊找鬼。 笑死狠轻,一個胖子當著我的面吹牛奸例,可吹牛的內容都是我干的。 我是一名探鬼主播向楼,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼查吊,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了湖蜕?” 一聲冷哼從身側響起逻卖,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎昭抒,沒想到半個月后评也,有當地人在樹林里發(fā)現了一具尸體炼杖,經...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年盗迟,在試婚紗的時候發(fā)現自己被綠了坤邪。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡罚缕,死狀恐怖艇纺,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情邮弹,我是刑警寧澤黔衡,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站腌乡,受9級特大地震影響盟劫,放射性物質發(fā)生泄漏周拐。R本人自食惡果不足惜涣仿,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望甸私。 院中可真熱鬧渣锦,春花似錦硝岗、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至听盖,卻和暖如春胀溺,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背皆看。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工仓坞, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人腰吟。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓无埃,卻偏偏與公主長得像,于是被迫代替她去往敵國和親毛雇。 傳聞我的和親對象是個殘疾皇子嫉称,可洞房花燭夜當晚...
    茶點故事閱讀 44,979評論 2 355

推薦閱讀更多精彩內容

  • 前言 Flutter是谷歌的移動UI框架,可以快速在iOS和Android上構建高質量的原生用戶界面灵疮。 IT界著名...
    IT小孢子閱讀 4,229評論 1 9
  • 《花樣年華》 曾經聽說過這部電影织阅,張曼玉與梁朝偉主演的,想著應該是描述青春時期一些趣事的電影震捣,看了之后荔棉,才覺得...
    WM9011閱讀 196評論 0 0
  • 2019.3.4星期一闹炉,天氣晴,(388)三年級一班劉紫涵 早上吃過飯閨女去上學了润樱,等二寶醒已經八點半了剩胁,趁她...
    鳳舞涵歆閱讀 217評論 0 0
  • 雄壯威武氣如山,步履鏗鏘意志堅祥国。 八年降魔驅倭寇,掃蔣剿匪令膽寒晾腔。 歷經二萬五千里舌稀,鐵骨錚錚驚地天。 不怕流血不流...
    鎮(zhèn)賚338于德旭閱讀 230評論 0 3
  • 這幾天速讀了扎克伯格灼擂。 先談收獲壁查。 天才的成長過程的確給人鼓舞和激勵,但給我更深感受的剔应,是他的努力睡腿。他對一項事物的...
    金露閱讀 392評論 0 1