在開發(fā)電商app的時候,用戶會需要點開查看商品的大圖
此文章用到了第三方的package: photo_view朴皆,hero動畫 可參考【Flutter實戰(zhàn)第二版】的介紹
主要涉及到兩個文件:animation_net_image.dart和image_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)面徽;就可以了