image_viewer_page.dart 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. import 'package:flutter/material.dart';
  2. import 'package:flutter_screenutil/flutter_screenutil.dart';
  3. import 'package:get/get.dart';
  4. import 'package:keyboard/base/base_page.dart';
  5. import 'package:keyboard/data/bean/image_viewer_item.dart';
  6. import 'package:keyboard/resource/colors.gen.dart';
  7. import 'package:keyboard/resource/string.gen.dart';
  8. import 'package:keyboard/router/app_page_arguments.dart';
  9. import 'package:keyboard/router/app_pages.dart';
  10. import 'package:photo_view/photo_view.dart';
  11. import '../../../resource/assets.gen.dart';
  12. import 'image_viewer_controller.dart';
  13. /// 图片预览页
  14. class ImageViewerPage extends BasePage<ImageViewerController> {
  15. const ImageViewerPage({super.key});
  16. /// 跳转
  17. /// [imageViewerItemList] 图片预览数据列表
  18. /// [index] 当前预览的索引,默认为0
  19. static void start(
  20. List<ImageViewerItem> imageViewerItemList, {
  21. int index = 0,
  22. }) {
  23. Map<String, dynamic> args = {
  24. AppPageArguments.imageViewerItemList: imageViewerItemList,
  25. AppPageArguments.index: index,
  26. };
  27. Get.toNamed(RoutePath.imageViewer, arguments: args);
  28. }
  29. @override
  30. backgroundColor() => ColorName.black;
  31. @override
  32. immersive() {
  33. // 沉浸式页面
  34. return true;
  35. }
  36. @override
  37. bool statusBarDarkFont() {
  38. // 状态栏,白色字体
  39. return false;
  40. }
  41. @override
  42. Widget buildBody(BuildContext context) {
  43. return Scaffold(
  44. body: Stack(
  45. children: [
  46. // 预览图
  47. Obx(() {
  48. return PageView.builder(
  49. controller: controller.pageController,
  50. itemCount: controller.imageViewerItemList.length,
  51. onPageChanged: (index) {
  52. // 更新当前索引
  53. controller.updateCurrentIndex(index);
  54. },
  55. itemBuilder: (context, index) {
  56. // 构建每一个PhotoView
  57. return _buildPhotoView(
  58. controller.imageViewerItemList[index],
  59. index,
  60. );
  61. },
  62. );
  63. }),
  64. // 指示器
  65. Visibility(
  66. visible: false,
  67. child: Positioned(
  68. left: 0,
  69. right: 0,
  70. bottom: 40.h,
  71. child: Obx(() {
  72. return _buildIndicator();
  73. }),
  74. ),
  75. ),
  76. // 标题栏
  77. Positioned(
  78. left: 0,
  79. top: 0,
  80. right: 0,
  81. child: Column(children: [_buildStatusBar(), _buildTitleBar()]),
  82. ),
  83. ],
  84. ),
  85. );
  86. }
  87. /// 指示器
  88. Widget _buildIndicator() {
  89. return Center(
  90. child: Row(
  91. mainAxisSize: MainAxisSize.min,
  92. children: [
  93. Text(
  94. '${controller.currentIndex.value + 1}/${controller.imageViewerItemList.length}',
  95. style: TextStyle(
  96. color: Colors.white,
  97. fontSize: 18.sp,
  98. fontWeight: FontWeight.w500,
  99. ),
  100. ),
  101. ],
  102. ),
  103. );
  104. }
  105. /// 状态栏占位
  106. Widget _buildStatusBar() {
  107. double statusBarHeight = MediaQuery.of(Get.context!).padding.top;
  108. return Container(
  109. // 导航栏高度
  110. height: statusBarHeight,
  111. color: backgroundColor(),
  112. );
  113. }
  114. /// 标题栏
  115. Widget _buildTitleBar() {
  116. return Container(
  117. height: kToolbarHeight,
  118. // 宽度,匹配父组件
  119. width: double.infinity,
  120. color: ColorName.black,
  121. padding: EdgeInsets.symmetric(horizontal: 16.0, vertical: 14.0),
  122. child: Stack(
  123. children: [
  124. // 返回按钮
  125. GestureDetector(
  126. onTap: controller.clickBack,
  127. child: Assets.images.iconImageViewerClose.image(
  128. width: 24.w,
  129. height: 24.h,
  130. ),
  131. ),
  132. // 标题
  133. Positioned(
  134. left: 0,
  135. top: 0,
  136. right: 0,
  137. child: Container(
  138. alignment: Alignment.center,
  139. child: Text(
  140. StringName.preview,
  141. style: TextStyle(
  142. fontSize: 16.sp,
  143. fontWeight: FontWeight.w500,
  144. color: ColorName.white,
  145. ),
  146. ),
  147. ),
  148. ),
  149. ],
  150. ),
  151. );
  152. }
  153. /// 每一页的PhotoView
  154. Widget _buildPhotoView(ImageViewerItem item, int index) {
  155. final photoViewController = controller.photoViewControllers.putIfAbsent(
  156. index,
  157. () => PhotoViewController(),
  158. );
  159. return PhotoView(
  160. // 设置图片ImageProvider
  161. imageProvider: controller.getImageProvider(item),
  162. controller: photoViewController,
  163. minScale: PhotoViewComputedScale.contained,
  164. maxScale: PhotoViewComputedScale.covered * 2,
  165. // 禁止旋转
  166. enableRotation: false,
  167. // 背景色
  168. backgroundDecoration: BoxDecoration(color: ColorName.black),
  169. // 加载中
  170. loadingBuilder: (_, __) => Center(child: CircularProgressIndicator()),
  171. );
  172. }
  173. }