import 'package:clean/base/base_page.dart'; import 'package:clean/module/screenshots_blurry/screenshots_controller.dart'; import 'package:clean/resource/assets.gen.dart'; import 'package:clean/router/app_pages.dart'; import 'package:flutter/Material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; import 'package:wechat_assets_picker/wechat_assets_picker.dart'; class ScreenshotsPage extends BasePage { const ScreenshotsPage({super.key}); static void start(String titleName) { Get.toNamed(RoutePath.screenshots, arguments: { "titleName": titleName, }); } @override bool statusBarDarkFont() { return false; } @override bool immersive() { return true; } @override Widget buildBody(BuildContext context) { return Stack(children: [ PopScope( canPop: false, onPopInvokedWithResult: (didPop, result) { if (didPop) { return; } controller.clickBack(); }, child: Container( child: SafeArea( child: Obx(() { if (controller.photoGroups.isEmpty || controller.photoGroups[0].images.isEmpty) { return _noNoPicturesCard(); } return Column( children: [ _titleCard(), Flexible( child: Obx(() { return SizedBox( child: GridView.builder( padding: EdgeInsets.symmetric(horizontal: 16.w), scrollDirection: Axis.vertical, // 设置为垂直方向滚动 physics: BouncingScrollPhysics(), gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 3, // 每行显示 2 个元素 mainAxisSpacing: 8.w, // 垂直间距 crossAxisSpacing: 8.h, // 水平间距 ), itemCount: controller.photoGroups[0].images.length, itemBuilder: _buildPhotoItem( controller.photoGroups[0].images)), ); }), ), Obx(() { if (controller.selectedPhotosIds.isNotEmpty) { return _bottomBarCard(); } else { return SizedBox(); } }), SizedBox(height: 8.h), ], ); }), ), ), ), IgnorePointer( child: Assets.images.bgHome.image( width: 360.w, ), ), ]); } Widget _titleCard() { return Container( alignment: Alignment.centerLeft, padding: EdgeInsets.only(left: 16.w, top: 14.h, right: 16.w), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Obx(() { return Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ GestureDetector( onTap: controller.clickBack, child: Assets.images.iconBackArrow.image( width: 28.w, height: 28.h, ), ), // 如果photoGroup数据为空,不显示全选按钮 controller.photoGroups.isEmpty || controller.photoGroups[0].images.isEmpty ? Container() : GestureDetector( onTap: () => controller.toggleGroupSelection( controller.photoGroups[0].images), child: Obx(() => Text( controller .getGroupByImages( controller.photoGroups[0].images) .isSelected .value ? 'Deselect All' : 'Select All', style: TextStyle( color: Colors.white.withValues(alpha: 0.7), fontSize: 14.sp, fontWeight: FontWeight.w400, ), )), ), ], ); }), controller.photoGroups.isEmpty || controller.photoGroups[0].images.isEmpty ? Container() : Column( children: [ SizedBox(height: 12.h), Text( controller.titleName, style: TextStyle( color: Colors.white, fontSize: 24.sp, fontWeight: FontWeight.w700, ), ), SizedBox(height: 20.h), ], ), ], ), ); } Widget _bottomBarCard() { return GestureDetector( onTap: () { controller.clickDelete(); }, child: Container( width: 328.w, height: 48.h, decoration: ShapeDecoration( color: Color(0xFF0279FB), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10.r), ), ), padding: EdgeInsets.symmetric(horizontal: 16.w), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Assets.images.iconDelete.image( width: 18.w, height: 18.h, ), SizedBox(width: 5.w), Obx(() { return Text( '${controller.selectedFileCount.value} files selected (${controller.selectedFilesSizeString})', textAlign: TextAlign.center, style: TextStyle( color: Colors.white, fontSize: 16.sp, fontWeight: FontWeight.w500, ), ); }), ], ), )); } Widget Function(BuildContext, int) _buildPhotoItem( List images) => (context, index) { final group = controller.getGroupByImages(controller.photoGroups[0].images); return GestureDetector( onTap: () => controller.clickImage(images, index, controller.getPhotosType()), child: Obx(() { var isSelected = group.selectedImages[index]; return Stack( children: [ Container( width: 104.w, height: 104.w, decoration: ShapeDecoration( color: Colors.white.withValues(alpha: 0.12), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(9.27.sp), ), image: DecorationImage( image: AssetEntityImageProvider( group.images[index], thumbnailSize: const ThumbnailSize.square(300), isOriginal: false, ), fit: BoxFit.cover, ), ), ), Positioned( right: 8.w, bottom: 8.h, child: GestureDetector( onTap: () => controller.toggleImageSelection(images, index), child: Container( child: isSelected ? Center( child: Assets.images.iconSelected.image( width: 20.w, height: 20.h, ), ) : Center( child: Assets.images.iconUnselected.image( width: 20.w, height: 20.h, )), )), ), ], ); }), ); }; Widget _noNoPicturesCard() { return Column( mainAxisAlignment: MainAxisAlignment.start, children: [ _titleCard(), SizedBox(height: 170.h), 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, ), ), ], ), ], ); } }