import 'dart:math' as math; import 'package:easy_refresh/easy_refresh.dart'; 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:gradient_borders/box_borders/gradient_box_border.dart'; import 'package:wallpaperx/common/components/image_network_widget.dart'; import 'package:wallpaperx/entity/image_model.dart'; import 'package:wallpaperx/generated/assets.dart'; import 'search_image_controller.dart'; class SearchImageView extends GetView { const SearchImageView({super.key}); @override Widget build(BuildContext context) { return Scaffold( resizeToAvoidBottomInset: false, body: Container( decoration: const BoxDecoration( image: DecorationImage( image: AssetImage(Assets.imagesRecommendTopBackground), fit: BoxFit.cover, ), ), child: GetBuilder( builder: (controller) => Obx( () => Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox( height: MediaQuery.of(context).padding.top, ), _buildSearchInput(), if (controller.searchList.isNotEmpty) ...[ Container( padding: const EdgeInsets.symmetric(horizontal: 15).w, child: Text( "ALL ${controller.total}", style: TextStyle(color: Colors.white, fontSize: 20.sp), ), ), 10.verticalSpace, _buildMasonryGridView(), ] else ...[ Expanded(child: Container()), _buildTags(context), ] ], ), ), ), ), ); } Widget _buildMasonryGridView() { return Expanded( child: EasyRefresh( controller: controller.refreshController, onLoad: controller.onLoad, child: Scrollbar( controller: controller.scrollController, child: Container( margin: const EdgeInsets.symmetric(horizontal: 15).w, child: MasonryGridView.count( controller: controller.scrollController, itemCount: controller.searchList.length, crossAxisCount: 2, mainAxisSpacing: 15.w, crossAxisSpacing: 15.w, padding: EdgeInsets.zero, itemBuilder: (context, index) { ImageModel item = controller.searchList[index]; return GestureDetector( onTap: () => controller.toImageDetail(index), child: ImageNetworkWidget( url: item.imageUrl, aspectRatio: item.width! / item.height!, radius: 15.r, ), ); }, ), ), ), ), ); } Widget _buildSearchInput() { return Row( children: [ TextButton( onPressed: () => Get.back(), child: Image.asset( Assets.iconBack, width: 30.w, height: 30.w, color: Colors.white, ), ), Expanded( child: Container( height: 40.w, alignment: Alignment.center, margin: const EdgeInsets.fromLTRB(0, 16, 16, 16).w, decoration: BoxDecoration( borderRadius: BorderRadius.circular(50).r, border: Border.all(color: Colors.white), ), child: Row( children: [ 10.horizontalSpace, Expanded( child: TextField( onSubmitted: (e) => controller.searchImages(), focusNode: controller.searchFocusNode, onTapOutside: (e) => {controller.searchFocusNode.unfocus()}, autofocus: false, controller: controller.searchController, maxLines: 1, style: TextStyle( color: Colors.white, fontSize: 14.sp, height: 1.4, ), decoration: InputDecoration( icon: Image.asset( width: 24.w, Assets.iconSearchInput, ), hintText: 'Input value', hintStyle: TextStyle( height: 1.4, fontSize: 14.sp, color: Colors.grey, ), contentPadding: const EdgeInsets.fromLTRB( -10, -10, 10, -10, ).w, border: const OutlineInputBorder( borderSide: BorderSide.none, ), counterText: "", ), ), ), ], ), ), ), ], ); } Widget _buildTags(context) { return Container( width: double.infinity, padding: EdgeInsets.only( bottom: MediaQuery.of(context).padding.bottom + 10, ), child: Column( children: [ Row( crossAxisAlignment: CrossAxisAlignment.end, children: [ Expanded( child: Container( margin: EdgeInsets.only(bottom: 15.w), child: labelOptionColourItem( "Anime Characters", Text( "Anime Characters", style: TextStyle( fontSize: 32.sp, color: const Color.fromRGBO(255, 255, 255, 0.85), ), ), angle: 12.0 * (math.pi / 180.0), ), ), ), 10.horizontalSpace, Container( child: labelOptionItem( "", Image.asset( width: 40.w, Assets.iconArrowTop, ), padding: const EdgeInsets.all(13).w), ), ], ), 10.verticalSpace, Row( crossAxisAlignment: CrossAxisAlignment.end, children: [ labelOptionItem( "", SizedBox( width: 40.w, height: 40.w, ), angle: 0.0 * (math.pi / 180.0), padding: const EdgeInsets.all(13).w, ), 15.horizontalSpace, Expanded( child: Container( child: labelOptionColourItem( "Landscape", Text( "Landscape", style: TextStyle( fontSize: 32.sp, color: const Color.fromRGBO(255, 255, 255, 0.85), ), ), ), ), ), ], ), 10.verticalSpace, Row( crossAxisAlignment: CrossAxisAlignment.end, children: [ Expanded( child: Container( child: labelOptionItem( "Fantasy", Text( "Fantasy", style: TextStyle( fontSize: 32.sp, color: const Color.fromRGBO(255, 255, 255, 0.85), ), ), ), ), ), 25.horizontalSpace, labelOptionItem( "", SizedBox( width: 40.w, height: 40.w, ), angle: 0.0 * (math.pi / 180.0), padding: const EdgeInsets.all(13).w, ), 32.horizontalSpace, labelOptionItem( "", SizedBox( width: 40.w, height: 40.w, ), angle: 0.0 * (math.pi / 180.0), padding: const EdgeInsets.all(13).w, ), ], ), 10.verticalSpace, Row( crossAxisAlignment: CrossAxisAlignment.end, children: [ labelOptionItem( "", Image.asset( width: 40.w, Assets.iconArrowBottomRight, ), angle: 0.0 * (math.pi / 180.0), padding: const EdgeInsets.all(13).w, ), 15.horizontalSpace, Expanded( child: Container( child: labelOptionItem( "Anime-style", Text( "Anime-style", style: TextStyle( fontSize: 32.sp, color: const Color.fromRGBO(255, 255, 255, 0.85), ), ), ), ), ), ], ), 10.verticalSpace, Row( crossAxisAlignment: CrossAxisAlignment.end, children: [ Expanded( child: Container( child: labelOptionItem( "Illustration", Text( "Illustration", style: TextStyle( fontSize: 32.sp, color: const Color.fromRGBO(255, 255, 255, 0.85), ), ), ), ), ), 22.horizontalSpace, labelOptionItem( "", Image.asset( width: 40.w, Assets.iconArrowBottom, ), angle: 0.0 * (math.pi / 180.0), padding: const EdgeInsets.all(13).w, ), ], ), ], ), ); } Widget labelOptionColourItem(tag, tagWidget, {double? angle, EdgeInsetsGeometry? padding}) { return GestureDetector( onTap: () => controller.inputSearchText(tag), child: Transform.rotate( angle: angle ?? 0.0 * (math.pi / 180.0), child: Container( decoration: BoxDecoration( border: const GradientBoxBorder( gradient: LinearGradient(colors: [ Color(0xffBEEF32), Color(0xff2795E5), Color(0xff8041FD), ]), width: 1, ), borderRadius: BorderRadius.circular(50.r), ), child: Container( alignment: Alignment.center, padding: padding ?? const EdgeInsets.symmetric(vertical: 10).w, child: tagWidget, ), ), ), ); } Widget labelOptionItem(tag, tagWidget, {double? angle, EdgeInsetsGeometry? padding}) { return GestureDetector( onTap: () => controller.inputSearchText(tag), child: Transform.rotate( angle: angle ?? 0.0 * (math.pi / 180.0), child: Container( alignment: Alignment.center, padding: padding ?? const EdgeInsets.symmetric(vertical: 10).w, decoration: BoxDecoration( borderRadius: BorderRadius.circular(50).r, border: Border.all(color: const Color.fromRGBO(255, 255, 255, 0.85)), ), child: tagWidget, ), ), ); } }