preview_photo_page.dart 6.1 KB

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