calendar_view.dart 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. import 'dart:ui';
  2. import 'package:get/get.dart';
  3. import 'package:clean/module/calendar/calendar_controller.dart';
  4. import 'package:flutter/Material.dart';
  5. import 'package:flutter_screenutil/flutter_screenutil.dart';
  6. import 'package:wechat_assets_picker/wechat_assets_picker.dart';
  7. import '../../base/base_view.dart';
  8. import '../../resource/assets.gen.dart';
  9. import '../people_photo/photo_group.dart';
  10. import 'calendar_state.dart';
  11. class CalendarPage extends BaseView<CalendarController> {
  12. const CalendarPage({super.key});
  13. @override
  14. Color backgroundColor() => const Color(0xFF05050D); // 修正返回类型
  15. @override
  16. double viewHeight() => double.infinity; // 统一返回类型
  17. @override
  18. Widget buildBody(BuildContext context) {
  19. return Stack(
  20. children: [
  21. SafeArea(
  22. child: CustomScrollView(
  23. slivers: [
  24. SliverToBoxAdapter(child: titleCard()),
  25. Obx(() {
  26. if (controller.monthlyAlbums.isEmpty) {
  27. return SliverToBoxAdapter(child: _noNoPicturesCard());
  28. }
  29. return SliverList(
  30. delegate: SliverChildBuilderDelegate(
  31. (context, index) {
  32. return monthCard(controller.monthlyAlbums[index]);
  33. },
  34. childCount: controller.monthlyAlbums.length, // 添加 itemCount
  35. ),
  36. );
  37. }),
  38. SliverToBoxAdapter(child: SizedBox(height: 40.h)),
  39. ],
  40. ),
  41. ),
  42. IgnorePointer(
  43. child: Assets.images.bgHome.image(
  44. width: 360.w,
  45. ),
  46. ),
  47. ],
  48. );
  49. }
  50. Widget titleCard() {
  51. return Padding(
  52. padding: EdgeInsets.only(left: 20.w, right: 20.w, top: 20.h),
  53. child: Row(
  54. children: [
  55. Text(
  56. 'Memory Lane',
  57. textAlign: TextAlign.center,
  58. style: TextStyle(
  59. color: Colors.white,
  60. fontSize: 24.sp,
  61. fontWeight: FontWeight.w900,
  62. ),
  63. ),
  64. Spacer(),
  65. GestureDetector(
  66. onTap: () => controller.clickSort(),
  67. child: Assets.images.iconCalendarSort.image(width: 28.w, height: 28.w)),
  68. ],
  69. ),
  70. );
  71. }
  72. Widget monthCard(PhotoGroup photoGroup) {
  73. return GestureDetector(
  74. onTap: () => controller.clickMonthCard(photoGroup),
  75. child: Container(
  76. margin: EdgeInsets.only(left: 16.w, right: 16.w, top: 12.h),
  77. width: 328.w,
  78. height: 209.h,
  79. decoration: ShapeDecoration(
  80. color: Colors.white.withValues(alpha: 0.12),
  81. shape: RoundedRectangleBorder(
  82. borderRadius: BorderRadius.circular(14.sp),
  83. ),
  84. ),
  85. child: Column(
  86. crossAxisAlignment: CrossAxisAlignment.start,
  87. children: [
  88. Spacer(),
  89. Padding(
  90. padding: EdgeInsets.only(left: 12.0.w, right: 12.0.w),
  91. child: Row(
  92. children: [
  93. Text(
  94. CalendarState.formatMonth(photoGroup.month ?? ""),
  95. style: TextStyle(
  96. color: Colors.white,
  97. fontSize: 16.sp,
  98. fontWeight: FontWeight.w700,
  99. ),
  100. ),
  101. Spacer(),
  102. Obx(() {
  103. return Text(
  104. '${photoGroup.selectedCount}/${photoGroup.images
  105. .length}',
  106. textAlign: TextAlign.center,
  107. style: TextStyle(
  108. color: Colors.white.withValues(alpha: 0.8),
  109. fontSize: 12.sp,
  110. fontWeight: FontWeight.w500,
  111. ),
  112. );
  113. }),
  114. ],
  115. ),
  116. ),
  117. Spacer(),
  118. Row(
  119. mainAxisAlignment: MainAxisAlignment.spaceEvenly,
  120. children: List.generate(2, (index) {
  121. if (index < photoGroup.images.length) {
  122. return GestureDetector(
  123. onTap: () => controller.clickImage(photoGroup, index),
  124. child: Stack(
  125. children: [
  126. Container(
  127. width: 146.w,
  128. height: 146.w,
  129. decoration: BoxDecoration(
  130. borderRadius: BorderRadius.circular(12.r),
  131. image: DecorationImage(
  132. image: AssetEntityImageProvider(
  133. photoGroup.images[index],
  134. isOriginal: false,
  135. ),
  136. fit: BoxFit.cover,
  137. ),
  138. ),
  139. ),
  140. // 如果是视频,显示时长
  141. if (photoGroup.images[index].type == AssetType.video)
  142. Positioned(
  143. bottom: 8.w,
  144. right: 8.w,
  145. child: Container(
  146. padding: EdgeInsets.symmetric(horizontal: 6.w, vertical: 2.h),
  147. decoration: BoxDecoration(
  148. color: Colors.black54,
  149. borderRadius: BorderRadius.circular(6.r),
  150. ),
  151. child: Text(
  152. CalendarState.formatDuration(photoGroup.images[index].duration),
  153. style: TextStyle(color: Colors.white, fontSize: 12.sp),
  154. ),
  155. ),
  156. ),
  157. ],
  158. ),
  159. );
  160. } else {
  161. return Container(
  162. width: 146.w,
  163. height: 146.w,
  164. decoration: BoxDecoration(
  165. borderRadius: BorderRadius.circular(12.r),
  166. ),
  167. );
  168. }
  169. }),
  170. ),
  171. Spacer(),
  172. ],
  173. ),
  174. ));
  175. }
  176. Widget _noNoPicturesCard() {
  177. return Column(
  178. children: [
  179. SizedBox(
  180. height: 170.h,
  181. ),
  182. Container(
  183. child: Column(
  184. mainAxisAlignment: MainAxisAlignment.center,
  185. crossAxisAlignment: CrossAxisAlignment.center,
  186. children: [
  187. Container(
  188. width: 70.w,
  189. height: 70.h,
  190. clipBehavior: Clip.antiAlias,
  191. decoration: BoxDecoration(),
  192. child: Assets.images.iconNoPictures.image(),
  193. ),
  194. SizedBox(height: 22.h),
  195. Text(
  196. 'No pictures found',
  197. textAlign: TextAlign.center,
  198. style: TextStyle(
  199. color: Colors.white,
  200. fontSize: 20.sp,
  201. fontWeight: FontWeight.w700,
  202. ),
  203. ),
  204. SizedBox(height: 12.h),
  205. Text(
  206. 'No pictures available at the moment',
  207. textAlign: TextAlign.center,
  208. style: TextStyle(
  209. color: Colors.white.withValues(alpha: 0.6),
  210. fontSize: 14.sp,
  211. fontWeight: FontWeight.w400,
  212. ),
  213. ),
  214. ],
  215. ),
  216. ),
  217. ],
  218. );
  219. }
  220. }