Skip to content

Commit

Permalink
feat:#17 search 위젯 전역 위젯화(#19), 후원처 검색 모듈 생성
Browse files Browse the repository at this point in the history
  • Loading branch information
kimwest00 committed Oct 8, 2023
1 parent 9886b51 commit b1c6587
Show file tree
Hide file tree
Showing 7 changed files with 353 additions and 14 deletions.
38 changes: 24 additions & 14 deletions lib/modules/donate/view/donate_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import 'package:match/modules/donate/widget/donate_widget.dart';
import 'package:match/util/const/style/global_text_styles.dart';

import '../../../model/enum/project_type.dart';
import '../../../provider/routes/routes.dart';
import '../../../util/const/global_variable.dart';
import '../../../util/const/style/global_color.dart';
import '../controller/donate_controller.dart';
Expand All @@ -23,7 +24,8 @@ class DonateScreen extends GetView<DonateController> {
children: [
//*1.제목 header
Padding(
padding: EdgeInsets.symmetric(vertical: 8.h),
padding:
EdgeInsets.symmetric(vertical: 8.h).copyWith(bottom: 25.h),
child: Row(
children: [
Expanded(
Expand All @@ -32,11 +34,23 @@ class DonateScreen extends GetView<DonateController> {
style: AppTextStyles.T1Bold16,
),
),
SvgPicture.asset(iconDir + "ic_search_16.svg"),
GestureDetector(
onTap: () async {
await Get.toNamed(Routes.donation_search);
},
child: SvgPicture.asset(
iconDir + "ic_search_16.svg",
color: AppColors.grey9,
height: 20.h,
),
),
SizedBox(
width: 14.w,
),
SvgPicture.asset(iconDir + "ic_alarm_20.svg")
SvgPicture.asset(
iconDir + "ic_alarm_20.svg",
height: 20.h,
)
],
),
),
Expand Down Expand Up @@ -70,8 +84,6 @@ class DonateScreen extends GetView<DonateController> {
}),
),
),
//TODO: obx 에러 임시처리
Text(controller.selectIdx.value.toString()),
//*3.정렬기준
Padding(
padding: EdgeInsets.only(top: 26.h),
Expand Down Expand Up @@ -112,15 +124,13 @@ class DonateScreen extends GetView<DonateController> {
itemCount: controller.projectList.length,
itemBuilder: (context, index) {
final project = controller.projectList[index];
if (index == 0) {
return Column(
children: [
SizedBox(height: 12.h),
ProjectWidget(project: project)
],
);
}
return ProjectWidget(project: project);
return Container(
margin: EdgeInsets.only(
top: index == 0 ? 14.h : 0.h,
bottom: index == controller.projectList.length - 1
? 14.h
: 0.h),
child: ProjectWidget(project: project));
},
),
),
Expand Down
10 changes: 10 additions & 0 deletions lib/modules/donation_search/binding/donation_search_binding.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import 'package:get/get.dart';

import '../controller/donation_search_controller.dart';

class DonationSearchBinding extends Bindings {
@override
void dependencies() {
Get.put(() => DonationSearchController());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import 'dart:async';

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:logger/logger.dart';
import 'package:match/model/project/project.dart';
import 'package:match/model/recent_search/recent_search.dart';
import 'package:match/modules/home/widget/home_widget.dart';
import 'package:match/util/method/get_storage.dart';

import '../../../model/enum/search_statu.dart';
import '../../../model/search/search.dart';

class DonationSearchController extends GetxController {
//검색 필드 controller
Rx<TextEditingController> searchTextController = TextEditingController().obs;
//최근 검색어 list
RxList<RecentSearch> recentSearchList = <RecentSearch>[].obs;

//최근 검색어 위젯 활성화 여부
Rx<SEARCH_STATUS> searchStatus = SEARCH_STATUS.INIT.obs;

///* 아래 함수에서 사용하는 1초를 측정하는 Timer
Timer? _timer;

///* 1초를 초기화하는 로직
Future<void> resetTimer() async {
_timer?.cancel();
_timer = null;
}

///* 검색 필드에 입력이 없을 때 1초 후에 api 호출하는 로직을 위해
///textFieldController에 listener를 등록하는 함수
Future<void> addTimerListenr() async {
searchTextController.value.addListener(() async {
if (searchTextController.value.text.isNotEmpty &&
searchStatus.value == SEARCH_STATUS.EDIT) {
// 입력이 없을 때 타이머 시작
if (_timer == null) {
_timer = Timer(Duration(seconds: 1), () {
Logger().d('1초가 경과했습니다.');
//TODO: api 호출
searchStatus.value = SEARCH_STATUS.SEARCH;
});
}
} else {
// 입력이 있으면 타이머 초기화
await resetTimer();
}
});
}

@override
Future<void> dispose() async {
searchTextController.value.dispose();
await resetTimer();
super.dispose();
}

@override
void onInit() async {
super.onInit();
recentSearchList.value = await GetStorageUtil.getRecentSearches();
await addTimerListenr();
}
}
138 changes: 138 additions & 0 deletions lib/modules/donation_search/view/donation_search_view.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
import 'dart:async';

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:get/get.dart';
import 'package:match/util/method/get_storage.dart';

import '../../../model/enum/search_statu.dart';
import '../../../model/recent_search/recent_search.dart';
import '../../../util/const/global_variable.dart';
import '../../../util/const/style/global_color.dart';
import '../../../util/const/style/global_text_styles.dart';
import '../controller/donation_search_controller.dart';

class DonationSearchScreen extends GetView<DonationSearchController> {
const DonationSearchScreen({super.key});

@override
Widget build(BuildContext context) {
Get.put(DonationSearchController());
return Scaffold(
body: Padding(
padding: EdgeInsets.symmetric(horizontal: 20.w, vertical: 10.h),
child: Obx(
() => ListView(
shrinkWrap: true,
children: [
//1. 뒤로가기 아이콘 + 검색 필드
Row(
children: [
GestureDetector(
onTap: () {
Get.back();
},
child: SvgPicture.asset(
iconDir + "ic_arrow_left_24.svg",
width: 24.w,
)),
SizedBox(
width: 14.w,
),
Expanded(
child: CupertinoTextField(
controller: controller.searchTextController.value,
padding:
EdgeInsets.symmetric(vertical: 10.h, horizontal: 12.w),
decoration: BoxDecoration(
color: AppColors.searchBackground,
borderRadius: BorderRadius.circular(8.r),
),
keyboardType: TextInputType.text,
cursorColor: AppColors.black,
cursorHeight: 18.h,
style: AppTextStyles.L1Medium13.copyWith(
color: AppColors.grey8,
height: 1.5,
),
placeholder: "고유 이름을 입력해보세요.",
placeholderStyle: AppTextStyles.L1Medium13.copyWith(
color: AppColors.grey4, height: 1.5),
prefixMode: OverlayVisibilityMode.notEditing,
prefix: Padding(
padding: EdgeInsets.only(left: 14.w),
child: SvgPicture.asset(iconDir + "ic_search_16.svg")),
// clearButtonMode: OverlayVisibilityMode.editing,
suffixMode: OverlayVisibilityMode.editing,
suffix: GestureDetector(
onTap: () async {
controller.searchTextController.value.clear();
controller.searchStatus.value = SEARCH_STATUS.INIT;
controller.recentSearchList.value =
await GetStorageUtil.getRecentSearches();
},
child: Padding(
padding: EdgeInsets.only(right: 14.w),
child: SvgPicture.asset(
iconDir + "ic_search_cancel_22.svg")),
),
//자동 키보드 활성화
autofocus: true,
onSubmitted: ((value) async {
controller.searchStatus.value = SEARCH_STATUS.SEARCH;
}),
onChanged: ((value) async {
controller.searchStatus.value = SEARCH_STATUS.EDIT;
}),
),
)
],
),
SizedBox(
height: 30.h,
),
// 검색 field 바로 밑에 제목
//1. 입력안했을때 최근검색어 리스트
controller.searchStatus.value == SEARCH_STATUS.INIT
? Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"최근 검색 고유이름",
style: AppTextStyles.T1Bold15,
),
GestureDetector(
onTap: () async {
await GetStorageUtil.delAllSearch();
controller.recentSearchList.value =
await GetStorageUtil.getRecentSearches();
},
child: Text(
"모두 삭제",
style: AppTextStyles.T1Bold12.copyWith(
color: AppColors.grey6),
),
),
],
)
: controller.searchStatus.value == SEARCH_STATUS.SEARCH
? Text(
"총 개의 검색결과",
style: AppTextStyles.T1Bold13.copyWith(
color: AppColors.grey5,
fontWeight: FontWeight.w600),
)
: SizedBox.shrink(),
SizedBox(
height: 20.h,
),
// 검색 field 밑의 contents
],
),
),
));
}
}
11 changes: 11 additions & 0 deletions lib/provider/routes/pages.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import 'package:match/modules/buring_match/view/burning_match_pay_view.dart';
import 'package:match/modules/buring_match/view/burning_match_view.dart';
import 'package:match/modules/donate/binding/donate_binding.dart';
import 'package:match/modules/donate/view/donate_view.dart';
import 'package:match/modules/donation_search/binding/donation_search_binding.dart';
import 'package:match/modules/donation_search/view/donation_search_view.dart';
import 'package:match/modules/mypage/binding/mypage_binding.dart';
import 'package:match/modules/mypage/view/mypage_view.dart';
import 'package:match/modules/onboarding/binding/onboarding_binding.dart';
Expand Down Expand Up @@ -151,5 +153,14 @@ class Pages {
curve: Curves.easeIn,
popGesture: false,
),
GetPage(
title: "검색 화면",
name: Routes.donation_search,
page: () => const DonationSearchScreen(),
transition: Transition.noTransition,
binding: DonationSearchBinding(),
curve: Curves.easeIn,
popGesture: false,
),
];
}
6 changes: 6 additions & 0 deletions lib/provider/routes/routes.dart
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ abstract class _Paths {
/// 후원 화면
static const donate = "/donate";

/// 후원 검색 화면
static const donation_search = "/donate_search";

/// 이벤트 화면
static const event = "/event";

Expand Down Expand Up @@ -77,6 +80,9 @@ abstract class Routes {
/// 후원 화면
static const donate = _Paths.donate;

/// 후원 검색 화면
static const donation_search = _Paths.donation_search;

/// 이벤트 화면
static const event = _Paths.event;

Expand Down
Loading

0 comments on commit b1c6587

Please sign in to comment.