screenshots_view.dart 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  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. import '../../utils/styles.dart';
  10. class ScreenshotsPage extends BasePage<ScreenShotsController> {
  11. const ScreenshotsPage({super.key});
  12. static void start(String titleName) {
  13. Get.toNamed(RoutePath.screenshots, arguments: {
  14. "titleName": titleName,
  15. });
  16. }
  17. @override
  18. bool statusBarDarkFont() {
  19. return false;
  20. }
  21. @override
  22. bool immersive() {
  23. return true;
  24. }
  25. @override
  26. Widget buildBody(BuildContext context) {
  27. return Stack(children: [
  28. PopScope(
  29. canPop: false,
  30. onPopInvokedWithResult: (didPop, result) {
  31. if (didPop) {
  32. return;
  33. }
  34. controller.clickBack();
  35. },
  36. child: Container(
  37. child: SafeArea(
  38. child: Obx(() {
  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. ),
  80. IgnorePointer(
  81. child: Assets.images.bgHome.image(
  82. width: 360.w,
  83. ),
  84. ),
  85. ]);
  86. }
  87. Widget _titleCard() {
  88. return Container(
  89. alignment: Alignment.centerLeft,
  90. padding: EdgeInsets.only(left: 16.w, top: 14.h, right: 16.w),
  91. child: Column(
  92. crossAxisAlignment: CrossAxisAlignment.start,
  93. children: [
  94. Obx(() {
  95. return Row(
  96. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  97. children: [
  98. GestureDetector(
  99. onTap: controller.clickBack,
  100. child: Assets.images.iconBackArrow.image(
  101. width: 28.w,
  102. height: 28.h,
  103. ),
  104. ),
  105. // 如果photoGroup数据为空,不显示全选按钮
  106. controller.photoGroups.isEmpty ||
  107. controller.photoGroups[0].images.isEmpty
  108. ? Container()
  109. : GestureDetector(
  110. onTap: () => controller.toggleGroupSelection(
  111. controller.photoGroups[0].images),
  112. child: Obx(() => Text(
  113. controller
  114. .getGroupByImages(
  115. controller.photoGroups[0].images)
  116. .isSelected
  117. .value
  118. ? 'Deselect All'
  119. : 'Select All',
  120. style: TextStyle(
  121. color: Colors.white.withValues(alpha: 0.7),
  122. fontSize: 14.sp,
  123. fontWeight: FontWeight.w400,
  124. ),
  125. )),
  126. ),
  127. ],
  128. );
  129. }),
  130. controller.photoGroups.isEmpty ||
  131. controller.photoGroups[0].images.isEmpty
  132. ? Container()
  133. : Column(
  134. children: [
  135. SizedBox(height: 12.h),
  136. Text(
  137. controller.titleName,
  138. style: TextStyle(
  139. color: Colors.white,
  140. fontSize: 24.sp,
  141. fontWeight: FontWeight.w700,
  142. ),
  143. ),
  144. SizedBox(height: 20.h),
  145. ],
  146. ),
  147. ],
  148. ),
  149. );
  150. }
  151. Widget _bottomBarCard() {
  152. return GestureDetector(
  153. onTap: () {
  154. controller.clickDelete();
  155. },
  156. child: Container(
  157. width: 328.w,
  158. height: 48.h,
  159. decoration: ShapeDecoration(
  160. color: Color(0xFF0279FB),
  161. shape: RoundedRectangleBorder(
  162. borderRadius: BorderRadius.circular(10.r),
  163. ),
  164. ),
  165. padding: EdgeInsets.symmetric(horizontal: 16.w),
  166. child: Row(
  167. mainAxisAlignment: MainAxisAlignment.center,
  168. children: [
  169. Assets.images.iconDelete.image(
  170. width: 18.w,
  171. height: 18.h,
  172. ),
  173. SizedBox(width: 5.w),
  174. Obx(() {
  175. return Text(
  176. 'Delete ${controller.selectedFileCount.value} Photos (${controller.selectedFilesSizeString})',
  177. textAlign: TextAlign.center,
  178. style: TextStyle(
  179. color: Colors.white,
  180. fontSize: 16.sp,
  181. fontWeight: FontWeight.w500,
  182. ),
  183. );
  184. }),
  185. ],
  186. ),
  187. ));
  188. }
  189. Widget Function(BuildContext, int) _buildPhotoItem(
  190. List<AssetEntity> images) =>
  191. (context, index) {
  192. final group =
  193. controller.getGroupByImages(controller.photoGroups[0].images);
  194. return GestureDetector(
  195. onTap: () =>
  196. controller.clickImage(images, index, controller.getPhotosType()),
  197. child: Obx(() {
  198. var isSelected = group.selectedImages[index];
  199. return Stack(
  200. children: [
  201. Container(
  202. width: 104.w,
  203. height: 104.w,
  204. decoration: ShapeDecoration(
  205. color: Colors.white.withValues(alpha: 0.12),
  206. shape: RoundedRectangleBorder(
  207. borderRadius: BorderRadius.circular(9.27.sp),
  208. ),
  209. ),
  210. child: ClipRRect(
  211. borderRadius: BorderRadius.circular(9.27.sp),
  212. child: AssetEntityImage(
  213. group.images[index],
  214. width: 104.w,
  215. height: 104.w,
  216. thumbnailSize: const ThumbnailSize.square(300),
  217. fit: BoxFit.cover,
  218. frameBuilder: Styles.customFrameBuilder(
  219. opacity: 0.22,
  220. width: 80.w,
  221. height: 80.w,
  222. ),
  223. isOriginal: false,
  224. ),
  225. )),
  226. Positioned(
  227. right: 8.w,
  228. bottom: 8.h,
  229. child: GestureDetector(
  230. onTap: () =>
  231. controller.toggleImageSelection(images, index),
  232. child: Container(
  233. child: isSelected
  234. ? Center(
  235. child: Assets.images.iconSelected.image(
  236. width: 20.w,
  237. height: 20.h,
  238. ),
  239. )
  240. : Center(
  241. child: Assets.images.iconUnselected.image(
  242. width: 20.w,
  243. height: 20.h,
  244. )),
  245. )),
  246. ),
  247. ],
  248. );
  249. }),
  250. );
  251. };
  252. Widget _noNoPicturesCard() {
  253. return Column(
  254. mainAxisAlignment: MainAxisAlignment.start,
  255. children: [
  256. _titleCard(),
  257. SizedBox(height: 170.h),
  258. Column(
  259. mainAxisAlignment: MainAxisAlignment.center,
  260. crossAxisAlignment: CrossAxisAlignment.center,
  261. children: [
  262. Container(
  263. width: 70.w,
  264. height: 70.h,
  265. clipBehavior: Clip.antiAlias,
  266. decoration: BoxDecoration(),
  267. child: Assets.images.iconNoPictures.image(),
  268. ),
  269. SizedBox(height: 22.h),
  270. Text(
  271. 'No pictures found',
  272. textAlign: TextAlign.center,
  273. style: TextStyle(
  274. color: Colors.white,
  275. fontSize: 20.sp,
  276. fontWeight: FontWeight.w700,
  277. ),
  278. ),
  279. SizedBox(height: 12.h),
  280. Text(
  281. 'No pictures available at the moment',
  282. textAlign: TextAlign.center,
  283. style: TextStyle(
  284. color: Colors.white.withValues(alpha: 0.6),
  285. fontSize: 14.sp,
  286. fontWeight: FontWeight.w400,
  287. ),
  288. ),
  289. ],
  290. ),
  291. ],
  292. );
  293. }
  294. }