flutter中自定義一個點擊圖片放大的widget

在開發(fā)電商app的時候,用戶會需要點開查看商品的大圖

此文章用到了第三方的package: photo_view朴皆,hero動畫 可參考【Flutter實戰(zhàn)第二版】的介紹
主要涉及到兩個文件:animation_net_image.dartimage_browser.dart
animation_net_image.dart這個文件是自定義可點擊放大的圖片;
image_browser.dart主要是顯示放大圖片的瀏覽器

1.直接上代碼(animation_net_image.dart)

import 'package:flutter/widgets.dart';
import 'package:yp_erp/Common/Util/image_url_format.dart';
import 'package:yp_erp/Common/Util/image_url_util.dart';
import 'package:yp_erp/Common/View/image_browser.dart';

class AnimationImageBuild extends StatefulWidget {
  final String heroTag;// 一定要保證和其他頁面不一樣
  final String imageURL; // 原圖片url
  final BoxFit fit;
  final double width;
  final double height;

  const AnimationImageBuild(
    this.imageURL,
    this.width,
    this.height,
    this.heroTag,
    this.fit, {
    Key key,
  }) : super(key: key);

  @override
  _AnimationImageBuildState createState() => _AnimationImageBuildState();
}

class _AnimationImageBuildState extends State<AnimationImageBuild> {
  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () {
        showImageBrowser(
          context,
          0,
          [ImageUrlUtil.formatUrl(widget.imageURL)],
          heroTag: widget.heroTag + widget.imageURL,
        );
      },
      child: Hero(
        tag: widget.heroTag + widget.imageURL,
        child: Image.network(
          resizeImageUrlFill(
              widget.imageURL, widget.height.round(), widget.width.round()),
          height: widget.height,
          width: widget.width,
          fit: widget.fit,
        ),
      ),
    );
  }
}

resizeImageUrlFill和ImageUrlUtil.formatUr主要是我們自己對圖片的處理,你自己傳圖片url即可

2.(image_browser.dart)文件

import 'package:flutter/material.dart';
import 'package:photo_view/photo_view.dart';
import 'package:photo_view/photo_view_gallery.dart';

void showImageBrowser(
  BuildContext context,
  final int index,
  List<String> imageURLs, {
  bool verticalGallery = false,
  Object heroTag = 0,
}) {
  Navigator.push(
    context,
    MaterialPageRoute(
      builder: (context) => GalleryPhotoViewWrapper(
        imageURLs: imageURLs,
        backgroundDecoration: const BoxDecoration(
          color: Colors.black,
        ),
        heroTag: heroTag,
        initialIndex: index,
        scrollDirection: verticalGallery ? Axis.vertical : Axis.horizontal,
      ),
    ),
  );
}

class GalleryPhotoViewWrapper extends StatefulWidget {
  final LoadingBuilder loadingBuilder;
  final BoxDecoration backgroundDecoration;
  final dynamic minScale;
  final dynamic maxScale;
  final int initialIndex;
  final Object heroTag;
  final PageController pageController;
  final List<String> imageURLs;
  final Axis scrollDirection;

  GalleryPhotoViewWrapper({
    Key key,
    this.loadingBuilder,
    this.backgroundDecoration,
    this.minScale,
    this.maxScale,
    this.heroTag = 0,
    this.initialIndex = 0,
    @required this.imageURLs,
    this.scrollDirection = Axis.horizontal,
  })  : pageController = PageController(initialPage: initialIndex),
        super(key: key);

  @override
  State<StatefulWidget> createState() {
    return _GalleryPhotoViewWrapperState();
  }
}

class _GalleryPhotoViewWrapperState extends State<GalleryPhotoViewWrapper> {
  int currentIndex = 0;

  void onPageChanged(int index) {
    setState(() {
      currentIndex = index;
    });
  }

  @override
  Widget build(BuildContext context) {
    if (currentIndex == 0) {
      currentIndex = widget.initialIndex;
    }

    return Scaffold(
      body: Container(
        decoration: widget.backgroundDecoration,
        constraints: BoxConstraints.expand(
          height: MediaQuery.of(context).size.height,
        ),
        child: InkWell(
          onTap: () {
            Navigator.pop(context);
          },
          child: Stack(
            alignment: Alignment.bottomCenter,
            children: <Widget>[
              PhotoViewGallery.builder(
                scrollPhysics: const BouncingScrollPhysics(),
                builder: _buildItem,
                itemCount: widget.imageURLs.length,
                loadingBuilder: widget.loadingBuilder,
                backgroundDecoration: widget.backgroundDecoration,
                pageController: widget.pageController,
                onPageChanged: onPageChanged,
                scrollDirection: widget.scrollDirection,
              ),
              Container(
                padding: const EdgeInsets.only(bottom: 20, left: 20, right: 20),
                child: Text(
                  " ${currentIndex + 1} / ${widget.imageURLs.length}",
                  style: const TextStyle(
                    color: Colors.white,
                    fontSize: 17.0,
                    decoration: null,
                  ),
                ),
              )
            ],
          ),
        ),
      ),
    );
  }

  PhotoViewGalleryPageOptions _buildItem(BuildContext context, int index) {
    final String item = widget.imageURLs[index];
    return PhotoViewGalleryPageOptions(
      imageProvider: NetworkImage(item),
      initialScale: PhotoViewComputedScale.contained,
      minScale: PhotoViewComputedScale.contained * (0.5 + index / 10),
      maxScale: PhotoViewComputedScale.covered * 4.1,
      heroAttributes: PhotoViewHeroAttributes(tag: widget.heroTag),
    );
  }
}

用的時候舉個例子:AnimationImageBuild(url, 88, 88, "appraisal" + state.model.code, BoxFit.fill)面徽;就可以了

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
禁止轉(zhuǎn)載佩研,如需轉(zhuǎn)載請通過簡信或評論聯(lián)系作者。
  • 序言:七十年代末灼芭,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子般又,更是在濱河造成了極大的恐慌彼绷,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件茴迁,死亡現(xiàn)場離奇詭異寄悯,居然都是意外死亡,警方通過查閱死者的電腦和手機堕义,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進店門猜旬,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事洒擦〈徽” “怎么了?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵秘遏,是天一觀的道長丘薛。 經(jīng)常有香客問我,道長邦危,這世上最難降的妖魔是什么洋侨? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮倦蚪,結(jié)果婚禮上希坚,老公的妹妹穿的比我還像新娘。我一直安慰自己陵且,他們只是感情好裁僧,可當我...
    茶點故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著慕购,像睡著了一般聊疲。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上沪悲,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天获洲,我揣著相機與錄音,去河邊找鬼殿如。 笑死贡珊,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的涉馁。 我是一名探鬼主播门岔,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼烤送!你這毒婦竟也來了寒随?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤帮坚,失蹤者是張志新(化名)和其女友劉穎牢裳,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體叶沛,經(jīng)...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年忘朝,在試婚紗的時候發(fā)現(xiàn)自己被綠了灰署。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,902評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖溉箕,靈堂內(nèi)的尸體忽然破棺而出晦墙,到底是詐尸還是另有隱情,我是刑警寧澤肴茄,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布晌畅,位于F島的核電站,受9級特大地震影響寡痰,放射性物質(zhì)發(fā)生泄漏抗楔。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一拦坠、第九天 我趴在偏房一處隱蔽的房頂上張望连躏。 院中可真熱鬧,春花似錦贞滨、人聲如沸入热。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽勺良。三九已至,卻和暖如春骄噪,著一層夾襖步出監(jiān)牢的瞬間尚困,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工腰池, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留尾组,地道東北人。 一個月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓示弓,卻偏偏與公主長得像讳侨,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子奏属,可洞房花燭夜當晚...
    茶點故事閱讀 44,843評論 2 354

推薦閱讀更多精彩內(nèi)容