calendar_view.dart 8.0 KB

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