Wallpaper-Genie/lib/page/search/search_view.dart
xuhang-x 8a19590c06 1
2024-07-15 18:30:18 +08:00

364 lines
11 KiB
Dart

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<CSearchController> {
const SearchView({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
backgroundColor: Colors.black,
body: GetBuilder<CSearchController>(
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,
),
),
),
),
],
),
),
),
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,
),
),
);
}
}