preview_photo_page.dart 6.0 KB

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