오늘은 검색 기능을 구현해보자. 검색기능은 필터 기능과 and 조건으로 동작한다.
개발환경 : 윈도우11, 안드로이드 스튜디오, flutter 2.10.3
소스코드 위치 - 05_doto_Search · mike-bskim/todo_test (github.com)
todo_search.dart 생성 - 검색할 단어를 provider 로 구현
import 'package:equatable/equatable.dart';
import 'package:flutter/foundation.dart';
class TodoSearchState extends Equatable {
final String searchTerm;
const TodoSearchState({
required this.searchTerm,
});
factory TodoSearchState.init() {
return const TodoSearchState(searchTerm: '');
}
@override
List<Object> get props => [searchTerm];
@override
String toString() => 'TodoSearchState(searchTerm: $searchTerm)';
TodoSearchState copyWith({
String? searchTerm,
}) {
return TodoSearchState(
searchTerm: searchTerm ?? this.searchTerm,
);
}
}
class TodoSearch with ChangeNotifier {
TodoSearchState _state = TodoSearchState.init();
TodoSearchState get state => _state;
void setSearchTerm(String newSearchTerm) {
_state = _state.copyWith(searchTerm: newSearchTerm);
notifyListeners();
}
}
main.dart 수정 - provider(TodoSearch) 추가 및 provider(filteredTodos.update) 수정
return MultiProvider(
providers: [
ChangeNotifierProvider<TodoList>(create: (context) => TodoList(),),
ChangeNotifierProvider<TodoFilter>(create: (context) => TodoFilter(),),
ChangeNotifierProvider<TodoSearch>(create: (context) => TodoSearch(),),
ChangeNotifierProxyProvider3<TodoFilter, TodoSearch, TodoList,
FilteredTodos>(
create: (context) => FilteredTodos(),
update: (
BuildContext context,
TodoFilter todoFilter,
TodoSearch todoSearch,
TodoList todoList,
FilteredTodos? filteredTodos,
) =>
filteredTodos!..update(todoFilter, todoSearch, todoList),
),
],
child: MaterialApp(
title: 'TODOS',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const TodosScreen(),
),
);
filtered_todos.dart 수정 - update 로직변경
class FilteredTodos with ChangeNotifier {
FilteredTodosState _state = FilteredTodosState.initial();
FilteredTodosState get state => _state;
void update(
TodoFilter todoFilter,
TodoSearch todoSearch, // 인자추가
TodoList todoList,
) {
List<Todo> _filteredTodos;
// 핵심 부분. 필터의 조건에 맞는 리스트를 만드는 기능
switch (todoFilter.state.filter) {
case Filter.active:
_filteredTodos =
todoList.state.todos.where((Todo todo) => !todo.completed).toList();
break;
case Filter.completed:
_filteredTodos =
todoList.state.todos.where((Todo todo) => todo.completed).toList();
break;
case Filter.all:
default:
_filteredTodos = todoList.state.todos;
break;
}
// 로직 추가
if (todoSearch.state.searchTerm.isNotEmpty) {
_filteredTodos = _filteredTodos
.where((Todo todo) =>
todo.desc.toLowerCase().contains(todoSearch.state.searchTerm))
.toList();
}
_state = _state.copyWith(filteredTodos: _filteredTodos);
notifyListeners();
}
}
providers.dart 수정
export 'todo_list.dart';
export 'todo_filter.dart';
export 'filtered_todos.dart';
export 'todo_search.dart'; // 추가
todos_screen.dart 수정 - SearchAndFilterTodo 의 build 기능추가
@override
Widget build(BuildContext context) {
return Column(
children: [
TextFormField(
decoration: const InputDecoration(
labelText: 'Search todos',
border: InputBorder.none,
filled: true,
prefixIcon: Icon(Icons.search),
),
onChanged: (String? newSearchTerm) {
debugPrint('Search todos: $newSearchTerm');
if (newSearchTerm != null) {
// 기능추가
context.read<TodoSearch>().setSearchTerm(newSearchTerm);
}
},
),
const SizedBox(height: 10.0),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
filterButton(context, Filter.all),
filterButton(context, Filter.active),
filterButton(context, Filter.completed),
],
),
],
);
}
[참고자료] udemy - Flutter Provider Essential 코스 (Korean)
'Flutter > 10 app Todo with provider' 카테고리의 다른 글
[Flutter] App Todo(with Provider) - 6단계 리스트 삭제, 편집 (0) | 2022.05.20 |
---|---|
[Flutter] App Todo(with Provider) - 5단계 할일 개수 표시 (0) | 2022.05.20 |
[Flutter] App Todo(with Provider) - 3단계 필터 및 리스트, cascade notation (0) | 2022.05.18 |
[Flutter] App Todo(with Provider) - 2단계 모델링 및 리스트 관리 (0) | 2022.05.18 |
[Flutter] App Todo(with Provider) - 1단계 화면구성 (0) | 2022.05.13 |