screenshots_view.dart 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. import 'package:clean/base/base_page.dart';
  2. import 'package:clean/module/screenshots_blurry/screenshots_controller.dart';
  3. import 'package:clean/resource/assets.gen.dart';
  4. import 'package:clean/router/app_pages.dart';
  5. import 'package:flutter/Material.dart';
  6. import 'package:flutter_screenutil/flutter_screenutil.dart';
  7. import 'package:get/get.dart';
  8. import 'package:wechat_assets_picker/wechat_assets_picker.dart';
  9. class ScreenshotsPage extends BasePage<ScreenShotsController> {
  10. const ScreenshotsPage({super.key});
  11. static void start(String titleName) {
  12. Get.toNamed(RoutePath.screenshots, arguments: {
  13. "titleName": titleName,
  14. });
  15. }
  16. @override
  17. bool statusBarDarkFont() {
  18. return false;
  19. }
  20. @override
  21. bool immersive() {
  22. return true;
  23. }
  24. @override
  25. Widget buildBody(BuildContext context) {
  26. return Stack(children: [
  27. PopScope(canPop: false,
  28. onPopInvokedWithResult: (didPop, result) {
  29. if (didPop) {
  30. return;
  31. }
  32. controller.clickBack();
  33. },
  34. child:
  35. Container(
  36. child: SafeArea(
  37. child: Obx(()
  38. {
  39. if (controller.photoGroups.isEmpty ||
  40. controller.photoGroups[0].images.isEmpty) {
  41. return _noNoPicturesCard();
  42. }
  43. return Column(
  44. children: [
  45. _titleCard(),
  46. Flexible(
  47. child: Obx(() {
  48. return SizedBox(
  49. child: GridView.builder(
  50. padding: EdgeInsets.symmetric(horizontal: 16.w),
  51. scrollDirection: Axis.vertical,
  52. // 设置为垂直方向滚动
  53. physics: BouncingScrollPhysics(),
  54. gridDelegate:
  55. SliverGridDelegateWithFixedCrossAxisCount(
  56. crossAxisCount: 3, // 每行显示 2 个元素
  57. mainAxisSpacing: 8.w, // 垂直间距
  58. crossAxisSpacing: 8.h, // 水平间距
  59. ),
  60. itemCount: controller.photoGroups[0].images.length,
  61. itemBuilder: _buildPhotoItem(
  62. controller.photoGroups[0].images)),
  63. );
  64. }),
  65. ),
  66. Obx(() {
  67. if (controller.selectedPhotosIds.isNotEmpty) {
  68. return _bottomBarCard();
  69. } else {
  70. return SizedBox();
  71. }
  72. }),
  73. SizedBox(height: 8.h),
  74. ],
  75. );
  76. }),
  77. ),
  78. ),),
  79. IgnorePointer(
  80. child: Assets.images.bgHome.image(
  81. width: 360.w,
  82. height: 234.h,
  83. )
  84. ,
  85. )
  86. ,
  87. ]
  88. );
  89. }
  90. Widget _titleCard() {
  91. return Container(
  92. alignment: Alignment.centerLeft,
  93. padding: EdgeInsets.only(left: 16.w, top: 14.h, right: 16.w),
  94. child: Column(
  95. crossAxisAlignment: CrossAxisAlignment.start,
  96. children: [
  97. Obx(() {
  98. return Row(
  99. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  100. children: [
  101. GestureDetector(
  102. onTap: controller.clickBack,
  103. child: Assets.images.iconBackArrow.image(
  104. width: 28.w,
  105. height: 28.h,
  106. ),
  107. ),
  108. // 如果photoGroup数据为空,不显示全选按钮
  109. controller.photoGroups.isEmpty ||
  110. controller.photoGroups[0].images.isEmpty
  111. ? Container()
  112. : GestureDetector(
  113. onTap: () =>
  114. controller.toggleGroupSelection(
  115. controller.photoGroups[0].images),
  116. child: Obx(() =>
  117. Text(
  118. controller
  119. .getGroupByImages(
  120. controller.photoGroups[0].images)
  121. .isSelected
  122. .value
  123. ? 'Deselect All'
  124. : 'Select All',
  125. style: TextStyle(
  126. color: Colors.white.withValues(alpha: 0.7),
  127. fontSize: 14.sp,
  128. fontWeight: FontWeight.w400,
  129. ),
  130. )),
  131. ),
  132. ],
  133. );
  134. }),
  135. controller.photoGroups.isEmpty ||
  136. controller.photoGroups[0].images.isEmpty
  137. ? Container()
  138. : Column(
  139. children: [
  140. SizedBox(height: 12.h),
  141. Text(
  142. controller.titleName,
  143. style: TextStyle(
  144. color: Colors.white,
  145. fontSize: 24.sp,
  146. fontWeight: FontWeight.w700,
  147. ),
  148. ),
  149. SizedBox(height: 20.h),
  150. ],
  151. ),
  152. ],
  153. ),
  154. );
  155. }
  156. Widget _bottomBarCard() {
  157. return GestureDetector(
  158. onTap: () {
  159. controller.clickDelete();
  160. },
  161. child: Container(
  162. width: 328.w,
  163. height: 48.h,
  164. decoration: ShapeDecoration(
  165. color: Color(0xFF0279FB),
  166. shape: RoundedRectangleBorder(
  167. borderRadius: BorderRadius.circular(10.r),
  168. ),
  169. ),
  170. padding: EdgeInsets.symmetric(horizontal: 16.w),
  171. child: Row(
  172. mainAxisAlignment: MainAxisAlignment.center,
  173. children: [
  174. Assets.images.iconDelete.image(
  175. width: 18.w,
  176. height: 18.h,
  177. ),
  178. SizedBox(width: 5.w),
  179. Obx(() {
  180. return Text(
  181. '${controller.selectedFileCount
  182. .value} files selected (${controller.selectedFilesSizeString})',
  183. textAlign: TextAlign.center,
  184. style: TextStyle(
  185. color: Colors.white,
  186. fontSize: 16.sp,
  187. fontWeight: FontWeight.w500,
  188. ),
  189. );
  190. }),
  191. ],
  192. ),
  193. ));
  194. }
  195. Widget Function(BuildContext, int) _buildPhotoItem(
  196. List<AssetEntity> images) =>
  197. (context, index) {
  198. final group =
  199. controller.getGroupByImages(controller.photoGroups[0].images);
  200. return GestureDetector(
  201. onTap: () =>
  202. controller.clickImage(images, index, controller.getPhotosType()),
  203. child: Obx(() {
  204. var isSelected = group.selectedImages[index];
  205. return Stack(
  206. children: [
  207. Container(
  208. width: 104.w,
  209. height: 104.w,
  210. decoration: ShapeDecoration(
  211. color: Colors.white.withValues(alpha: 0.12),
  212. shape: RoundedRectangleBorder(
  213. borderRadius: BorderRadius.circular(9.27.sp),
  214. ),
  215. image: DecorationImage(
  216. image: AssetEntityImageProvider(
  217. group.images[index],
  218. thumbnailSize: const ThumbnailSize.square(300),
  219. isOriginal: false,
  220. ),
  221. fit: BoxFit.cover,
  222. ),
  223. ),
  224. ),
  225. Positioned(
  226. right: 8.w,
  227. bottom: 8.h,
  228. child: GestureDetector(
  229. onTap: () =>
  230. controller.toggleImageSelection(images, index),
  231. child: Container(
  232. child: isSelected
  233. ? Center(
  234. child: Assets.images.iconSelected.image(
  235. width: 20.w,
  236. height: 20.h,
  237. ),
  238. )
  239. : Center(
  240. child: Assets.images.iconUnselected.image(
  241. width: 20.w,
  242. height: 20.h,
  243. )),
  244. )),
  245. ),
  246. ],
  247. );
  248. }),
  249. );
  250. };
  251. Widget _noNoPicturesCard() {
  252. return Column(
  253. mainAxisAlignment: MainAxisAlignment.start,
  254. children: [
  255. _titleCard(),
  256. SizedBox(height: 170.h),
  257. Column(
  258. mainAxisAlignment: MainAxisAlignment.center,
  259. crossAxisAlignment: CrossAxisAlignment.center,
  260. children: [
  261. Container(
  262. width: 70.w,
  263. height: 70.h,
  264. clipBehavior: Clip.antiAlias,
  265. decoration: BoxDecoration(),
  266. child: Assets.images.iconNoPictures.image(),
  267. ),
  268. SizedBox(height: 22.h),
  269. Text(
  270. 'No pictures found',
  271. textAlign: TextAlign.center,
  272. style: TextStyle(
  273. color: Colors.white,
  274. fontSize: 20.sp,
  275. fontWeight: FontWeight.w700,
  276. ),
  277. ),
  278. SizedBox(height: 12.h),
  279. Text(
  280. 'No pictures available at the moment',
  281. textAlign: TextAlign.center,
  282. style: TextStyle(
  283. color: Colors.white.withValues(alpha: 0.6),
  284. fontSize: 14.sp,
  285. fontWeight: FontWeight.w400,
  286. ),
  287. ),
  288. ],
  289. ),
  290. ],
  291. );
  292. }
  293. }