import 'dart:ui'; import 'package:get/get.dart'; import 'package:clean/module/calendar/calendar_controller.dart'; import 'package:flutter/Material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:lottie/lottie.dart'; import 'package:wechat_assets_picker/wechat_assets_picker.dart'; import '../../base/base_view.dart'; import '../../resource/assets.gen.dart'; import '../../utils/styles.dart'; import '../people_photo/photo_group.dart'; import 'calendar_state.dart'; class CalendarPage extends BaseView { const CalendarPage({super.key}); @override Color backgroundColor() => const Color(0xFF05050D); // 修正返回类型 @override double viewHeight() => double.infinity; // 统一返回类型 @override Widget buildBody(BuildContext context) { return Stack( children: [ SafeArea( child: CustomScrollView( slivers: [ SliverToBoxAdapter(child: titleCard()), Obx(() { if (controller.monthlyAlbums.isEmpty) { return SliverToBoxAdapter(child: _noNoPicturesCard()); } return SliverList( delegate: SliverChildBuilderDelegate( (context, index) { return monthCard(controller.monthlyAlbums[index]); }, childCount: controller.monthlyAlbums.length, // 添加 itemCount ), ); }), SliverToBoxAdapter(child: SizedBox(height: 40.h)), ], ), ), IgnorePointer( child: Assets.images.bgHome.image( width: 360.w, ), ), ], ); } Widget titleCard() { return Padding( padding: EdgeInsets.only(left: 20.w, right: 20.w, top: 20.h), child: Row( children: [ Text( 'Memory Lane', textAlign: TextAlign.center, style: TextStyle( color: Colors.white, fontSize: 24.sp, fontWeight: FontWeight.w900, ), ), Spacer(), GestureDetector( onTap: () => controller.clickSort(), child: Assets.images.iconCalendarSort .image(width: 28.w, height: 28.w)), ], ), ); } Widget monthCard(PhotoGroup photoGroup) { return GestureDetector( onTap: () => controller.clickMonthCard(photoGroup), child: Container( margin: EdgeInsets.only(left: 16.w, right: 16.w, top: 12.h), width: 328.w, height: 209.h, decoration: ShapeDecoration( color: Colors.white.withValues(alpha: 0.12), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(14.sp), ), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Spacer(), Padding( padding: EdgeInsets.only(left: 12.0.w, right: 12.0.w), child: Row( children: [ Text( CalendarState.formatMonth(photoGroup.month ?? ""), style: TextStyle( color: Colors.white, fontSize: 16.sp, fontWeight: FontWeight.w700, ), ), Spacer(), Obx(() { return Text( '${photoGroup.selectedCount}/${photoGroup.images.length}', textAlign: TextAlign.center, style: TextStyle( color: Colors.white.withValues(alpha: 0.8), fontSize: 12.sp, fontWeight: FontWeight.w500, ), ); }), ], ), ), Spacer(), Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: List.generate(2, (index) { if (index < photoGroup.images.length) { return GestureDetector( onTap: () => controller.clickImage(photoGroup, index), child: Stack( children: [ Container( width: 146.w, height: 146.w, decoration: BoxDecoration( borderRadius: BorderRadius.circular(12.r), ), child: ClipRRect( borderRadius: BorderRadius.circular(12.r), child: AssetEntityImage( width: 146.w, height: 146.w, fit: BoxFit.cover, photoGroup.images[index], frameBuilder: Styles.customFrameBuilder(), ), ), ), // 如果是视频,显示时长 if (photoGroup.images[index].type == AssetType.video) Positioned( bottom: 8.w, right: 8.w, child: Container( padding: EdgeInsets.symmetric( horizontal: 6.w, vertical: 2.h), decoration: BoxDecoration( color: Colors.black54, borderRadius: BorderRadius.circular(6.r), ), child: Text( CalendarState.formatDuration( photoGroup.images[index].duration), style: TextStyle( color: Colors.white, fontSize: 12.sp), ), ), ), ], ), ); } else { return Container( width: 146.w, height: 146.w, decoration: BoxDecoration( borderRadius: BorderRadius.circular(12.r), ), ); } }), ), Spacer(), ], ), )); } Widget _noNoPicturesCard() { return Column( children: [ SizedBox( height: 170.h, ), Container( child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ Container( width: 70.w, height: 70.h, clipBehavior: Clip.antiAlias, decoration: BoxDecoration(), child: Assets.images.iconNoPictures.image(), ), SizedBox(height: 22.h), Text( 'No pictures found', textAlign: TextAlign.center, style: TextStyle( color: Colors.white, fontSize: 20.sp, fontWeight: FontWeight.w700, ), ), SizedBox(height: 12.h), Text( 'No pictures available at the moment', textAlign: TextAlign.center, style: TextStyle( color: Colors.white.withValues(alpha: 0.6), fontSize: 14.sp, fontWeight: FontWeight.w400, ), ), ], ), ), ], ); } }