import 'dart:ui'; import 'package:cached_network_image/cached_network_image.dart'; import 'package:flip_card/flip_card.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; import 'package:photo_view/photo_view.dart'; import 'package:photo_view/photo_view_gallery.dart'; import 'package:wallpaperx/common/components/view_state_widget.dart'; import 'package:wallpaperx/entity/image_model.dart'; import 'package:wallpaperx/gen/assets.dart'; import 'package:wallpaperx/page/wallpaper_det_v2/wallpaper_det_v2_controller.dart'; class WallpaperDetV2View extends GetView { const WallpaperDetV2View({super.key}); @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.black, extendBodyBehindAppBar: true, extendBody: true, body: FlipCard( flipOnTouch: false, controller: controller.flipCardController, fill: Fill.fillBack, side: CardSide.FRONT, direction: FlipDirection.HORIZONTAL, front: Stack( fit: StackFit.expand, children: [ _buildPhotoView(), _buildBottomOption(context), ], ), back: _buildImageInfo(context), ), ); } /// 图片PageView Widget _buildPhotoView() { return Obx(() { if (controller.wallpaperList.isEmpty) { return Container(); } return PhotoViewGallery.builder( itemCount: controller.wallpaperList.length, scrollPhysics: const BouncingScrollPhysics(), wantKeepAlive: true, gaplessPlayback: true, builder: (context, index) { return PhotoViewGalleryPageOptions.customChild( child: PhotoView( enableRotation: true, imageProvider: CachedNetworkImageProvider( controller.wallpaperList[index].imageUrl, ), initialScale: PhotoViewComputedScale.covered, minScale: PhotoViewComputedScale.contained * 0.5, maxScale: PhotoViewComputedScale.covered * 3, loadingBuilder: (context, event) => loadingView(), errorBuilder: (BuildContext context, Object error, StackTrace? stackTrace) => errorView, ), ); }, pageController: controller.pageController, onPageChanged: (index) => controller.onPageChanged(index), ); }); } /// 底部选项 Widget _buildBottomOption(context) { return Positioned( bottom: 0, left: 0, right: 0, child: Column( children: [ ClipRect( child: BackdropFilter( filter: ImageFilter.blur(sigmaX: 10.0, sigmaY: 10.0), child: Container( padding: EdgeInsets.only( bottom: MediaQuery.of(context).padding.bottom), width: double.infinity, height: 70.h, decoration: const BoxDecoration( color: Color.fromRGBO(0, 0, 0, 0.65), ), clipBehavior: Clip.hardEdge, child: Row( children: [ 16.horizontalSpace, _buildOptionItem( Assets.imagesIcDelBack, 'Blur', controller.showAd, ), Expanded(child: Container()), Obx(() => _buildOptionItem( controller.isFavorite.value ? Assets.imagesIcFavorite : Assets.imagesIcUnFavorite, 'Favorite', controller.onTapFavorite, )), 24.horizontalSpace, _buildOptionItem( Assets.imagesIcDownload, 'Download', controller.onTapDownload, ), 24.horizontalSpace, _buildOptionItem( Assets.imagesIcInfo, 'Blur', controller.onTapToggleCard, ), 16.horizontalSpace, ], ), ), ), ), ], ), ); } /// 图片详情 Widget _buildImageInfo(context) { return GetBuilder( id: 'buildImageInfo', builder: (logic) { ImageModel model = controller.wallpaperList[controller.position]; return Container( clipBehavior: Clip.hardEdge, decoration: BoxDecoration( borderRadius: BorderRadius.circular(12).r, image: DecorationImage( fit: BoxFit.cover, image: CachedNetworkImageProvider( controller.wallpaperList[controller.position].imageUrl, ), ), ), child: BackdropFilter( filter: ImageFilter.blur(sigmaX: 10.0, sigmaY: 10.0), child: Container( padding: EdgeInsets.fromLTRB( 30, 0, 30, MediaQuery.of(context).padding.bottom + 55, ).w, width: double.infinity, decoration: BoxDecoration( color: const Color(0xff000000).withOpacity(.8), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ 63.verticalSpace, Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.start, children: [ 24.horizontalSpace, Stack( clipBehavior: Clip.none, children: [ Image.asset( Assets.imagesIcTip, width: 52.w, height: 52.w, ), Positioned( left: -15.w, top: 15.w, child: Image.asset( Assets.startS, width: 20.w, ), ), Positioned( left: -8.w, top: 10.w, child: Image.asset( Assets.startM, width: 20.w, ), ), Positioned( right: -12.w, bottom: -2.w, child: Image.asset( Assets.startL, width: 25.w, ), ), ], ), GestureDetector( onTap: controller.onTapToggleCard, child: Icon( Icons.close, color: Colors.white, size: 24.w, ), ), ], ), 37.verticalSpace, Expanded( child: ListView( padding: EdgeInsets.zero, children: [ Wrap( spacing: 8.w, runSpacing: 8.w, children: model.tags! .map((e) => tagItem(e.taglabel)) .toList(), ), 32.verticalSpace, genInfo( Image.asset( Assets.icSampler, width: 28.w, ), "Sampler:", model.generateInfo!.samplingMethod ?? "", ), 23.verticalSpace, genInfo( Image.asset( Assets.icCfgScale, width: 28.w, ), "CFG scale:", model.generateInfo!.cfgScale.toString(), ), 23.verticalSpace, genInfo( Image.asset( Assets.icSteps, width: 28.w, ), "Steps:", model.generateInfo!.samplingStep.toString(), ), 23.verticalSpace, genInfo( Image.asset( Assets.icSeed, width: 28.w, ), "Seed:", model.generateInfo!.seed.toString(), ), 20.verticalSpace, Text( "Prompt", textAlign: TextAlign.start, style: TextStyle(color: Colors.white, fontSize: 16.sp), ), 12.verticalSpace, Text( model.generateInfo?.prompt ?? "", textAlign: TextAlign.start, style: TextStyle( color: const Color(0xffA1A9B3), fontSize: 14.sp), ), 20.verticalSpace, Text( "Negative Prompt", textAlign: TextAlign.start, style: TextStyle(color: Colors.white, fontSize: 16.sp), ), 12.verticalSpace, Text( model.generateInfo?.negativePrompt ?? "", textAlign: TextAlign.start, style: TextStyle( color: const Color(0xffA1A9B3), fontSize: 14.sp), ), ], ), ), 24.verticalSpace, GestureDetector( onTap: () => controller.clipboard(model.generateInfo), child: Container( width: double.infinity, padding: const EdgeInsets.symmetric( vertical: 15, horizontal: 8) .w, decoration: BoxDecoration( color: const Color(0xff322E31), borderRadius: BorderRadius.circular(30).r, ), child: Text( "copy", textAlign: TextAlign.center, style: TextStyle(color: Colors.white, fontSize: 14.sp), ), ), ), ], ), ), ), ); }, ); } Widget genInfo(icon, title, content) { return Row( children: [ icon, 16.horizontalSpace, SizedBox( width: 250.w, child: Text( title + content, maxLines: 1, overflow: TextOverflow.ellipsis, textAlign: TextAlign.start, style: TextStyle(color: Colors.white, fontSize: 16.sp), ), ), ], ); } Widget tagItem(tag) { return GestureDetector( onTap: () => controller.onTapToClsDet(tag), child: Container( padding: const EdgeInsets.all(1), decoration: BoxDecoration( borderRadius: BorderRadius.circular(50).r, gradient: const LinearGradient( colors: [ Color(0xffBEEF32), Color(0xff2795E5), Color(0xff8041FD), ], ), ), child: Container( padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 12).w, decoration: BoxDecoration( borderRadius: BorderRadius.circular(50).r, color: Colors.black, ), child: Text( "#$tag", style: TextStyle(color: Colors.white, fontSize: 14.sp), ), ), ), ); } Widget _buildOptionItem(String iconName, String option, Function() onTap) { return Material( color: Colors.transparent, child: InkWell( onTap: onTap, child: Image.asset( iconName, width: 24.w, height: 24.w, color: Colors.white, ), ), ); } }