preview_photo_page.dart 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. import 'dart:io';
  2. import 'package:flutter/material.dart';
  3. import 'package:get/get.dart';
  4. import 'package:cs_resources/generated/assets.dart';
  5. import 'package:router/path/router_path.dart';
  6. import 'package:shared/utils/screen_util.dart';
  7. import 'package:widgets/my_load_image.dart';
  8. import 'package:widgets/my_text_view.dart';
  9. import 'package:cs_resources/constants/color_constants.dart';
  10. import '../base/base_stateful_page.dart';
  11. import 'package:extended_image/extended_image.dart';
  12. /*
  13. * 预览的图片的页面,内部使用PageView左右切换
  14. */
  15. class PreviewPhotoPage extends BaseStatefulPage {
  16. PreviewPhotoPage({super.key});
  17. //启动当前页面
  18. static Future<T?>? startInstance<T>(List<String> imgs, int position) {
  19. return Get.toNamed(RouterPath.PREVIEW_IMAGE, arguments: {'imgs': imgs, "position": position});
  20. }
  21. @override
  22. _PreviewPhotoPageState createState() => _PreviewPhotoPageState();
  23. @override
  24. GetxController createRawController() {
  25. throw UnimplementedError();
  26. }
  27. }
  28. class _PreviewPhotoPageState extends State<PreviewPhotoPage> {
  29. late List<String> images;
  30. int currentIndex = 0;
  31. @override
  32. void initState() {
  33. super.initState();
  34. images = Get.arguments['imgs'];
  35. currentIndex = Get.arguments['position'];
  36. }
  37. @override
  38. void dispose() {
  39. super.dispose();
  40. clearGestureDetailsCache();
  41. }
  42. @override
  43. Widget build(BuildContext context) {
  44. return Scaffold(
  45. backgroundColor: ColorConstants.black,
  46. body: SafeArea(
  47. bottom: true,
  48. top: false,
  49. //真正的 Content 布局
  50. child: Column(
  51. children: [
  52. SizedBox(height: ScreenUtil.getStatusBarH(context)),
  53. Row(
  54. children: [
  55. //间距
  56. SizedBox(width: 30),
  57. Expanded(
  58. child: MyTextView(
  59. "${currentIndex + 1}/${images.length}",
  60. textColor: Colors.white,
  61. fontSize: 18,
  62. isFontRegular: true,
  63. textAlign: TextAlign.center,
  64. ),
  65. ),
  66. InkWell(
  67. onTap: () {
  68. Get.back();
  69. },
  70. child: const MyAssetImage(
  71. Assets.baseLibDialogDeleteIcon,
  72. width: 14,
  73. height: 14,
  74. ),
  75. ),
  76. //间距
  77. SizedBox(width: 15),
  78. ],
  79. ),
  80. Expanded(
  81. child: ExtendedImageGesturePageView.builder(
  82. controller: ExtendedPageController(
  83. //图片PageView的配置选项
  84. initialPage: currentIndex,
  85. pageSpacing: 10,
  86. ),
  87. itemCount: images.length,
  88. scrollDirection: Axis.horizontal,
  89. onPageChanged: (int index) {
  90. setState(() {
  91. currentIndex = index;
  92. });
  93. },
  94. itemBuilder: (BuildContext context, int index) {
  95. //默认网络加载的占位图
  96. final Widget placeholder = Container(
  97. //如果没有设置占位图,使用默认的灰色背景内置Icon小图标
  98. width: double.infinity,
  99. height: double.infinity,
  100. color: ColorConstants.greye0,
  101. alignment: Alignment.center,
  102. child: const MyAssetImage(
  103. Assets.baseLibImageDefaultPlaceholder,
  104. width: 38,
  105. height: 32,
  106. ),
  107. );
  108. //区分网络图片和本地图片
  109. Widget image = images[index].startsWith("http")
  110. ? ExtendedImage.network(
  111. images[index],
  112. fit: BoxFit.contain,
  113. timeLimit: const Duration(milliseconds: 30000),
  114. cache: true,
  115. mode: ExtendedImageMode.gesture,
  116. loadStateChanged: (ExtendedImageState state) {
  117. switch (state.extendedImageLoadState) {
  118. case LoadState.loading:
  119. return placeholder;
  120. case LoadState.completed:
  121. return null;
  122. case LoadState.failed:
  123. return placeholder;
  124. }
  125. },
  126. initGestureConfigHandler: (ExtendedImageState state) {
  127. return GestureConfig(
  128. // 图片展示的配置选项
  129. inPageView: true,
  130. initialScale: 1.0,
  131. maxScale: 5.0,
  132. animationMaxScale: 6.0,
  133. initialAlignment: InitialAlignment.center,
  134. cacheGesture: false,
  135. );
  136. },
  137. )
  138. : ExtendedImage.file(
  139. File(images[index]),
  140. fit: BoxFit.contain,
  141. mode: ExtendedImageMode.gesture,
  142. initGestureConfigHandler: (ExtendedImageState state) {
  143. return GestureConfig(
  144. // 图片展示的配置选项
  145. inPageView: true,
  146. initialScale: 1.0,
  147. maxScale: 5.0,
  148. animationMaxScale: 6.0,
  149. initialAlignment: InitialAlignment.center,
  150. cacheGesture: false,
  151. );
  152. },
  153. );
  154. if (index == currentIndex) {
  155. return Hero(
  156. // tag: index.toString(),
  157. tag: "0",
  158. child: image,
  159. );
  160. } else {
  161. return image;
  162. }
  163. },
  164. )),
  165. ],
  166. ),
  167. ));
  168. }
  169. }