基础库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

232 lines
6.3 KiB

  1. import 'dart:io';
  2. import 'package:flutter/material.dart';
  3. import 'package:photo_view/photo_view.dart';
  4. import 'package:photo_view/photo_view_gallery.dart';
  5. import 'package:zhiying_comm/zhiying_comm.dart';
  6. ///图片预览控件
  7. class PhotoPreview extends StatefulWidget {
  8. List<PreviewImageData> previewImageDatas;
  9. int index;
  10. PhotoPreview({Key key, this.previewImageDatas, this.index = 0})
  11. : super(key: key);
  12. PhotoPreview._showPhotoViewByData(
  13. {Key key, this.previewImageDatas, this.index})
  14. : super(key: key);
  15. PhotoPreview._showPhotoViewByImages(
  16. {Key key, List<String> images, this.index})
  17. : super(key: key) {
  18. if (images != null) {
  19. previewImageDatas = List();
  20. for (var img in images) {
  21. previewImageDatas.add(PreviewImageData(
  22. previewImageType: PreviewImageType.netUrl, data: img));
  23. }
  24. }
  25. }
  26. ///显示类型的一些预览
  27. static showPhotoPreview(
  28. BuildContext context, List<PreviewImageData> previewImageDatas,
  29. {int currentIndex = 0}) {
  30. Navigator.of(context).push(new FadeRoute(
  31. page: PhotoPreview._showPhotoViewByData(
  32. previewImageDatas: previewImageDatas,
  33. index: currentIndex,
  34. )));
  35. }
  36. ///显示仅仅是一组list<String>类型的图片预览
  37. static showPhotoPreviewByimages(BuildContext context, List<String> images,
  38. {int currentIndex = 0}) {
  39. Navigator.of(context).push(new FadeRoute(
  40. page: PhotoPreview._showPhotoViewByImages(
  41. images: images,
  42. index: currentIndex,
  43. )));
  44. }
  45. @override
  46. _PhotoPreviewState createState() => _PhotoPreviewState();
  47. }
  48. class _PhotoPreviewState extends State<PhotoPreview> {
  49. PageController pageController;
  50. @override
  51. void initState() {
  52. pageController = PageController(keepPage: true, initialPage: widget.index);
  53. super.initState();
  54. }
  55. @override
  56. Widget build(BuildContext context) {
  57. return Scaffold(
  58. backgroundColor: Colors.transparent,
  59. body: PhotoViewGalleryScreen(
  60. images: widget.previewImageDatas,
  61. index: widget.index,
  62. controller: pageController,
  63. heroTag: "",
  64. ));
  65. }
  66. }
  67. ///图片预览数据
  68. class PreviewImageData {
  69. PreviewImageType previewImageType;
  70. String data;
  71. bool isSelect;
  72. String tag;
  73. PreviewImageData(
  74. {this.previewImageType, this.data, this.isSelect = false, this.tag});
  75. }
  76. ///预览类型
  77. enum PreviewImageType {
  78. netUrl,
  79. ///网络图片
  80. filePath
  81. ///本地文件路径
  82. }
  83. class PhotoViewGalleryScreen extends StatefulWidget {
  84. List<PreviewImageData> images = [];
  85. int index = 0;
  86. String heroTag;
  87. PageController controller;
  88. PhotoViewGalleryScreen(
  89. {Key key,
  90. @required this.images,
  91. this.index,
  92. this.controller,
  93. this.heroTag})
  94. : super(key: key) {
  95. controller = PageController(initialPage: index);
  96. }
  97. @override
  98. _PhotoViewGalleryScreenState createState() => _PhotoViewGalleryScreenState();
  99. }
  100. class _PhotoViewGalleryScreenState extends State<PhotoViewGalleryScreen> {
  101. int currentIndex = 0;
  102. @override
  103. void initState() {
  104. // TODO: implement initState
  105. super.initState();
  106. currentIndex = widget.index;
  107. }
  108. @override
  109. Widget build(BuildContext context) {
  110. return Scaffold(
  111. body: Stack(
  112. children: <Widget>[
  113. GestureDetector(
  114. onTap: () {
  115. Navigator.pop(context);
  116. },
  117. child: Container(
  118. color: Colors.black,
  119. child: PhotoViewGallery.builder(
  120. scrollPhysics: const BouncingScrollPhysics(),
  121. builder: (BuildContext context, int index) {
  122. return PhotoViewGalleryPageOptions(
  123. imageProvider: _buildPage(context, index),
  124. heroAttributes: widget.heroTag.isNotEmpty
  125. ? PhotoViewHeroAttributes(tag: widget.heroTag)
  126. : null,
  127. );
  128. },
  129. itemCount: widget.images.length,
  130. loadFailedChild: Container(
  131. child: Text("加载失败"),
  132. ),
  133. backgroundDecoration: BoxDecoration(color: Colors.black),
  134. pageController: widget.controller,
  135. enableRotation: true,
  136. onPageChanged: (index) {
  137. setState(() {
  138. currentIndex = index;
  139. });
  140. },
  141. )),
  142. ),
  143. Positioned(
  144. //图片index显示
  145. top: MediaQuery.of(context).padding.top + 15,
  146. width: MediaQuery.of(context).size.width,
  147. child: Container(
  148. child: Center(
  149. child: Text("${currentIndex + 1}/${widget.images.length}",
  150. style: TextStyle(color: Colors.white, fontSize: 16)),
  151. ),
  152. ),
  153. ),
  154. Positioned(
  155. //右上角关闭按钮
  156. right: 10,
  157. top: MediaQuery.of(context).padding.top,
  158. child: IconButton(
  159. icon: Icon(
  160. Icons.close,
  161. size: 30,
  162. color: Colors.white,
  163. ),
  164. onPressed: () {
  165. Navigator.of(context).pop();
  166. },
  167. ),
  168. ),
  169. ],
  170. ),
  171. );
  172. }
  173. ImageProvider _buildPage(BuildContext context, int index) {
  174. var item = widget.images[index];
  175. if (item.previewImageType == PreviewImageType.netUrl) {
  176. return CachedNetworkImageProvider(item.data);
  177. } else if (item.previewImageType == PreviewImageType.filePath) {
  178. return Image.file(File(item.data)).image;
  179. }
  180. }
  181. }
  182. class FadeRoute extends PageRouteBuilder {
  183. final Widget page;
  184. FadeRoute({this.page})
  185. : super(
  186. pageBuilder: (
  187. BuildContext context,
  188. Animation<double> animation,
  189. Animation<double> secondaryAnimation,
  190. ) =>
  191. page,
  192. transitionsBuilder: (
  193. BuildContext context,
  194. Animation<double> animation,
  195. Animation<double> secondaryAnimation,
  196. Widget child,
  197. ) =>
  198. ScaleTransition(
  199. scale: animation,
  200. child: FadeTransition(
  201. opacity: animation,
  202. child: child,
  203. ),
  204. ),
  205. );
  206. }