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:wallpaperx/common/components/image_network_widget.dart'; import 'package:wallpaperx/entity/image_model.dart'; import 'package:wallpaperx/gen/assets.dart'; import 'package:wallpaperx/page/search/search_controller.dart'; class SearchView extends GetView { const SearchView({super.key}); @override Widget build(BuildContext context) { return Scaffold( resizeToAvoidBottomInset: false, backgroundColor: Colors.black, body: GetBuilder( builder: (controller) => Obx( () => Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox( height: MediaQuery.of(context).padding.top, ), _buildSearchInput(), if (controller.searchList.isNotEmpty) ...[ 24.verticalSpace, Text( "ALL ${controller.total}", style: TextStyle(color: Colors.white, fontSize: 20.sp), ), 24.verticalSpace, _buildMasonryGridView(), ] else ...[ Expanded(child: Container()), _buildTags(context), ] ], ), ), ), ); } Widget _buildMasonryGridView() { return Expanded( child: EasyRefresh( controller: controller.refreshController, onLoad: controller.onLoad, child: MasonryGridView.count( itemCount: controller.searchList.length, crossAxisCount: 2, mainAxisSpacing: 20.w, crossAxisSpacing: 21.w, padding: EdgeInsets.zero, itemBuilder: (context, index) { ImageModel item = controller.searchList[index]; return GestureDetector( onTap: () => controller.onTapItem(index), child: ImageNetworkWidget( url: item.imageUrl, aspectRatio: item.width! / item.height!, radius: 14.r, ), ); }, ), ), ); } Widget _buildSearchInput() { return Row( children: [ Expanded( child: Container( height: 40.w, alignment: Alignment.center, margin: const EdgeInsets.all(16).w, decoration: BoxDecoration( borderRadius: BorderRadius.circular(50).r, color: const Color(0xff141414), ), child: Row( children: [ 10.horizontalSpace, Expanded( child: TextField( onSubmitted: (e) => controller.getImages(), 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.searchIcon, ), hintText: 'Title', hintStyle: TextStyle( height: 1.4, fontSize: 14.sp, color: const Color(0xff47474A)), contentPadding: const EdgeInsets.symmetric( vertical: -10, horizontal: -10, ), border: const OutlineInputBorder( borderSide: BorderSide.none, ), counterText: "", ), ), ), ], ), ), ), TextButton( onPressed: () => Get.back(), child: Text( "Cancel", style: TextStyle(color: Colors.white, fontSize: 16.sp), ), ) ], ); } Widget _buildTags(context) { return Container( width: double.infinity, padding: EdgeInsets.only(bottom: MediaQuery.of(context).padding.bottom), decoration: BoxDecoration( borderRadius: BorderRadius.circular(10).r, border: Border.all(color: Colors.black), ), child: Column( children: [ Row( crossAxisAlignment: CrossAxisAlignment.end, children: [ Expanded( child: Container( margin: EdgeInsets.only(bottom: 12.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.searchTop, ), 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.searchBottomRight, ), 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.searchBottom, ), 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.setSearchText(tag), child: Transform.rotate( angle: angle ?? 0.0 * (math.pi / 180.0), 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( alignment: Alignment.center, padding: padding ?? const EdgeInsets.symmetric(vertical: 10).w, decoration: BoxDecoration( borderRadius: BorderRadius.circular(50).r, color: Colors.black, ), child: tagWidget, ), ), ), ); } Widget labelOptionItem(tag, tagWidget, {double? angle, EdgeInsetsGeometry? padding}) { return GestureDetector( onTap: () => controller.setSearchText(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, ), ), ); } }