import 'dart:ui'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart'; import 'package:get/get.dart'; import 'package:wallpaperx/common/components/custom_stacked_list_widget.dart'; import 'package:wallpaperx/common/components/image_network_widget.dart'; import 'package:wallpaperx/common/components/navigation_bar/search_appbar.dart'; import 'package:wallpaperx/common/components/refresh/base_easyrefresh.dart'; import 'package:wallpaperx/common/components/view_state_widget.dart'; import 'package:wallpaperx/entity/image_model.dart'; import 'package:wallpaperx/generated/assets.dart'; import 'package:wallpaperx/global/app_config.dart'; import 'package:wallpaperx/res/themes/app_sizes.dart'; import 'recommend_controller.dart'; class RecommendView extends GetView { const RecommendView({super.key}); @override Widget build(BuildContext context) { Get.put(RecommendController()); return Scaffold( resizeToAvoidBottomInset: false, body: PageView( scrollDirection: Axis.vertical, children: [ _buildPhotoView(context), _buildMasonryGridView(context), ], ), ); } Widget _buildPhotoView(context) { return Stack( children: [ GetBuilder( id: 'discover_background', builder: (logic) { return Container( clipBehavior: Clip.hardEdge, width: double.infinity, height: double.infinity, decoration: const BoxDecoration( color: Colors.black87, ), child: ImageFiltered( imageFilter: ImageFilter.blur( sigmaX: 40, sigmaY: 40, tileMode: TileMode.decal, ), child: controller.banners.isEmpty ? Image.asset( Assets.imagesRecommendTopBackground, ) : ImageNetworkWidget( url: controller.banners[controller.index.value].imageUrl, radius: 30.r, width: 300.w, height: 500.w, fit: BoxFit.cover, ), ), ); }, ), SafeArea( bottom: false, child: Column( children: [ SearchAppbar( onTapToSearch: controller.toSearch, onTapToCategory: controller.homeController.openHomeDrawer, title: appName, showDown: false, titleStyle: TextStyle( color: Colors.white, fontSize: 24.sp, fontWeight: FontWeight.w600, ), ), 18.verticalSpace, Expanded( child: Obx( () => controller.banners.isEmpty ? loadingViewV1(color: Colors.white) : StackedListWidget( listItems: controller.banners .asMap() .entries .map( (e) => Container( key: Key(e.key.toString()), child: ImageNetworkWidget( url: controller.banners[e.key].imageUrl, radius: 30.r, width: 300.w, height: 500.w, fit: BoxFit.fitHeight, ), ), ) .toList(), listItemWidth: 200.w, animationDuration: const Duration(milliseconds: 350), borderRadius: BorderRadius.circular(30.r), rotationAngle: 4, additionalTranslateOffsetBeyondScreen: -92, onIndexChanged: controller.onIndexChanged, focusedItemShadow: [ BoxShadow( color: Colors.black.withOpacity(0.26), blurRadius: 28, spreadRadius: 8, offset: const Offset(8, 16), ), BoxShadow( color: Colors.black.withOpacity(0.26), blurRadius: 28, spreadRadius: 8, offset: const Offset(-8, 2), ), ], ), ), ), 18.verticalSpace, Image.asset( width: 24.w, Assets.iconUp, ), SizedBox(height: MediaQuery.of(context).padding.bottom + 72.w) ], ), ) ], ); } Widget _buildMasonryGridView(context) { return Container( decoration: const BoxDecoration( image: DecorationImage( image: AssetImage(Assets.imagesRecommendBottomBackground), fit: BoxFit.cover, ), ), child: SafeArea( bottom: false, child: Column( children: [ SearchAppbar( onTapToSearch: controller.toSearch, onTapToCategory: controller.homeController.openHomeDrawer, title: appName, titleStyle: TextStyle( color: Colors.white, fontSize: 24.sp, fontWeight: FontWeight.w600, ), ), Obx(() { return Expanded( child: BaseEasyRefresh( controller: controller.refreshController, onLoad: controller.onLoad, viewState: controller.viewState.value, height: discoverListHeight, child: Scrollbar( controller: controller.scrollController, child: MasonryGridView.count( controller: controller.scrollController, itemCount: controller.images.length, crossAxisCount: 2, mainAxisSpacing: 15.w, crossAxisSpacing: 15.w, padding: const EdgeInsets.fromLTRB(15, 0, 15, 0).w, itemBuilder: (context, index) { ImageModel item = controller.images[index]; return GestureDetector( onTap: () => controller.gridToImageDetail(index), child: ImageNetworkWidget( url: item.imageUrl, aspectRatio: item.width! / item.height!, radius: 15.r, ), ); }, ), ), ), ); }), ], ), ), ); } }