people_photo_view.dart 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. import 'dart:io';
  2. import 'package:clean/base/base_page.dart';
  3. import 'package:clean/module/image_picker/image_picker_util.dart';
  4. import 'package:clean/module/people_photo/people_photo_controller.dart';
  5. import 'package:clean/resource/assets.gen.dart';
  6. import 'package:clean/router/app_pages.dart';
  7. import 'package:flutter/Material.dart';
  8. import 'package:flutter/cupertino.dart';
  9. import 'package:flutter_screenutil/flutter_screenutil.dart';
  10. import 'package:get/get.dart';
  11. import 'package:wechat_assets_picker/wechat_assets_picker.dart';
  12. class PeoplePhotoPage extends BasePage<PeoplePhotoController> {
  13. const PeoplePhotoPage({super.key});
  14. static start() {
  15. Get.toNamed(RoutePath.peoplePhoto, arguments: {});
  16. }
  17. @override
  18. bool statusBarDarkFont() {
  19. // TODO: implement statusBarDarkFont
  20. return false;
  21. }
  22. @override
  23. bool immersive() {
  24. // TODO: implement immersive
  25. return true;
  26. }
  27. @override
  28. Widget buildBody(BuildContext context) {
  29. return Stack(children: [
  30. Container(
  31. child: SafeArea(
  32. child: Column(
  33. children: [
  34. _titleCard(),
  35. // Photo groups
  36. Expanded(
  37. child: Obx(() {
  38. return ListView(
  39. padding: EdgeInsets.symmetric(horizontal: 16.w),
  40. children: [
  41. ...controller.photoGroups.map((group) => Column(
  42. children: [
  43. _buildPhotoGroup(
  44. images: group.images,
  45. title: group.title,
  46. imageCount: group.imageCount,
  47. ),
  48. SizedBox(height: 15.h),
  49. ],
  50. ))
  51. ],
  52. );
  53. }),
  54. ),
  55. _bottomBarCard(),
  56. ],
  57. ),
  58. ),
  59. ),
  60. IgnorePointer(
  61. child: Assets.images.bgHome.image(
  62. width: 360.w,
  63. height: 234.h,
  64. ),
  65. ),
  66. ]);
  67. }
  68. Widget _titleCard() {
  69. return Container(
  70. alignment: Alignment.centerLeft,
  71. padding: EdgeInsets.only(left: 16.w, top: 14.h),
  72. child: Column(
  73. crossAxisAlignment: CrossAxisAlignment.start,
  74. children: [
  75. GestureDetector(
  76. onTap: () => Get.back(),
  77. child: Assets.images.iconBackArrow.image(
  78. width: 28.w,
  79. height: 28.h,
  80. ),
  81. ),
  82. SizedBox(height: 12.h),
  83. Text(
  84. 'People Photos',
  85. style: TextStyle(
  86. color: Colors.white,
  87. fontSize: 24.sp,
  88. fontWeight: FontWeight.w700,
  89. ),
  90. ),
  91. SizedBox(height: 20.h),
  92. ],
  93. ),
  94. );
  95. }
  96. Widget _bottomBarCard() {
  97. return Container(
  98. width: 360.w,
  99. height: 81.h,
  100. padding: EdgeInsets.symmetric(horizontal: 16.w),
  101. decoration: ShapeDecoration(
  102. color: Color(0xFF23232A),
  103. shape: RoundedRectangleBorder(
  104. side: BorderSide(
  105. width: 1.w, color: Colors.white.withValues(alpha: 0.1)),
  106. borderRadius: BorderRadius.only(
  107. topLeft: Radius.circular(14.r),
  108. topRight: Radius.circular(14.r),
  109. ),
  110. ),
  111. ),
  112. child: Row(
  113. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  114. children: [
  115. Obx(() {
  116. return Text(
  117. '${controller.selectedFileCount.value} files selected (${controller.selectedFilesSize.value.toStringAsFixed(1)} KB)',
  118. textAlign: TextAlign.center,
  119. style: TextStyle(
  120. color: Colors.white.withOpacity(0.9),
  121. fontSize: 13.sp,
  122. fontWeight: FontWeight.w500,
  123. ),
  124. );
  125. }),
  126. Container(
  127. width: 108.w,
  128. height: 38.h,
  129. decoration: ShapeDecoration(
  130. color: Color(0xFF0279FB),
  131. shape: RoundedRectangleBorder(
  132. borderRadius: BorderRadius.circular(10.r),
  133. ),
  134. ),
  135. child: Row(
  136. mainAxisAlignment: MainAxisAlignment.spaceEvenly,
  137. children: [
  138. Text(
  139. 'Delete',
  140. textAlign: TextAlign.center,
  141. style: TextStyle(
  142. color: Colors.white,
  143. fontSize: 16.sp,
  144. fontWeight: FontWeight.w500,
  145. ),
  146. ),
  147. Assets.images.iconDelete.image(
  148. width: 18.w,
  149. height: 18.h,
  150. ),
  151. ],
  152. ),
  153. ),
  154. ],
  155. ),
  156. );
  157. }
  158. Widget _buildPhotoGroup({
  159. required List<AssetEntity> images,
  160. required String title,
  161. required int imageCount,
  162. }) {
  163. return Container(
  164. padding: EdgeInsets.symmetric(horizontal: 12.w),
  165. margin: EdgeInsets.only(top: 14.h),
  166. width: 328.w,
  167. height: imageCount < 5 ? 160.h : 230.h,
  168. decoration: ShapeDecoration(
  169. color: Colors.white.withValues(alpha: 0.12),
  170. shape: RoundedRectangleBorder(
  171. borderRadius: BorderRadius.circular(14.sp),
  172. ),
  173. ),
  174. child: Column(
  175. mainAxisAlignment: MainAxisAlignment.spaceEvenly,
  176. children: [
  177. Row(
  178. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  179. children: [
  180. Text(
  181. title,
  182. textAlign: TextAlign.center,
  183. style: TextStyle(
  184. color: Colors.white,
  185. fontSize: 14.sp,
  186. fontWeight: FontWeight.w500,
  187. ),
  188. ),
  189. GestureDetector(
  190. onTap: () => controller.toggleGroupSelection(images),
  191. child: Obx(() => Text(
  192. controller.getGroupByImages(images).isSelected.value
  193. ? 'Deselect All'
  194. : 'Select All',
  195. style: TextStyle(
  196. color: Colors.white.withValues(alpha: 0.7),
  197. fontSize: 14.sp,
  198. fontWeight: FontWeight.w400,
  199. ),
  200. )),
  201. ),
  202. ],
  203. ),
  204. SizedBox(
  205. height: imageCount < 3
  206. ? 70.h
  207. : imageCount <= 8
  208. ? null
  209. : 148.h,
  210. child: imageCount <= 8
  211. ? GridView.builder(
  212. shrinkWrap: true,
  213. physics: NeverScrollableScrollPhysics(),
  214. gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
  215. crossAxisCount: 4,
  216. mainAxisSpacing: 8.w,
  217. crossAxisSpacing: 8.h,
  218. ),
  219. itemCount: imageCount,
  220. itemBuilder: _buildPhotoItem(images),
  221. )
  222. : GridView.builder(
  223. scrollDirection: Axis.horizontal,
  224. physics: BouncingScrollPhysics(),
  225. gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
  226. crossAxisCount: 2,
  227. mainAxisSpacing: 8.w,
  228. crossAxisSpacing: 8.h,
  229. childAspectRatio: 1,
  230. ),
  231. itemCount: imageCount,
  232. itemBuilder: _buildPhotoItem(images),
  233. ),
  234. ),
  235. ],
  236. ),
  237. );
  238. }
  239. Widget Function(BuildContext, int) _buildPhotoItem(
  240. List<AssetEntity> images) =>
  241. (context, index) {
  242. final group = controller.getGroupByImages(images);
  243. final assetEntity = group.images[index];
  244. return GestureDetector(
  245. onTap: () {
  246. controller.clickImage(images, index);
  247. print("点击图片");
  248. },
  249. child: Obx(() {
  250. final isSelected = group.selectedImages[index];
  251. return Stack(
  252. children: [
  253. Container(
  254. width: 70.w,
  255. height: 70.w,
  256. decoration: ShapeDecoration(
  257. color: Colors.white.withValues(alpha: 0.12),
  258. shape: RoundedRectangleBorder(
  259. borderRadius: BorderRadius.circular(9.27.sp),
  260. ),
  261. image: DecorationImage(
  262. image: AssetEntityImageProvider(
  263. assetEntity,
  264. isOriginal: false,
  265. ),
  266. fit: BoxFit.cover,
  267. ),
  268. ),
  269. ),
  270. Positioned(
  271. right: 6.w,
  272. bottom: 6.h,
  273. child: GestureDetector(
  274. onTap: () {
  275. controller.toggleImageSelection(images, index);
  276. },
  277. child: Container(
  278. child: isSelected
  279. ? Center(
  280. child: Assets.images.iconSelected.image(
  281. width: 20.w,
  282. height: 20.h,
  283. ),
  284. )
  285. : Center(
  286. child: Assets.images.iconUnselected.image(
  287. width: 20.w,
  288. height: 20.h,
  289. )),
  290. ),
  291. )),
  292. ],
  293. );
  294. }),
  295. );
  296. };
  297. }