안녕하세요, Flutter 개발자 여러분! 이번 포스팅에서는 Flutter 앱의 상태 관리를 개선하기 위해 Provider 라이브러리를 도입하는 방법에 대해 자세히 알아보겠습니다. 이전에 만든 To-Do 리스트 앱을 더욱 효율적이고 확장 가능한 구조로 개선해 볼 거예요.
1. 상태 관리의 중요성
먼저, 상태 관리가 왜 중요한지 이해해 봅시다. 앱이 커지고 복잡해질수록, 여러 위젯에서 공유되는 데이터(상태)를 관리하는 것이 어려워집니다. 효과적인 상태 관리는 다음과 같은 이점을 제공합니다:
- 코드의 가독성과 유지보수성 향상
- 성능 최적화
- 버그 발생 가능성 감소
- 기능 확장의 용이성
2. Provider 패키지 소개
Provider는 Flutter 팀이 추천하는 상태 관리 솔루션 중 하나입니다. 간단하면서도 강력한 이 라이브러리는 다음과 같은 장점이 있습니다:
- 사용하기 쉽습니다.
- Flutter의 위젯 트리와 자연스럽게 통합됩니다.
- 성능이 우수합니다.
- 테스트하기 쉽습니다.
3. Provider 설치하기
자, 이제 Provider를 우리 프로젝트에 추가해 봅시다.
pubspec.yaml
파일을 엽니다.dependencies
섹션에 다음 줄을 추가합니다:
dependencies:
flutter:
sdk: flutter
provider: ^6.0.0
- 터미널에서 다음 명령어를 실행합니다:
flutter pub get
이렇게 하면 Provider 패키지가 프로젝트에 설치됩니다.
4. 모델 클래스 생성하기
이제 우리 앱의 데이터 모델을 만들어 봅시다. lib
폴더 안에 models
폴더를 만들고, 그 안에 todo_model.dart
파일을 생성합니다.
import 'package:flutter/foundation.dart';
class Todo {
String id;
String title;
bool isCompleted;
Todo({required this.id, required this.title, this.isCompleted = false});
}
class TodoModel extends ChangeNotifier {
List<Todo> _todos = [];
List<Todo> get todos => _todos;
void addTodo(Todo todo) {
_todos.add(todo);
notifyListeners();
}
void toggleTodo(String id) {
final todo = _todos.firstWhere((todo) => todo.id == id);
todo.isCompleted = !todo.isCompleted;
notifyListeners();
}
void deleteTodo(String id) {
_todos.removeWhere((todo) => todo.id == id);
notifyListeners();
}
}
이 코드에 대해 자세히 설명해 드리겠습니다:
Todo
클래스는 각 할 일 항목을 나타냅니다.TodoModel
클래스는ChangeNotifier
를 상속받아 상태 변화를 알릴 수 있게 합니다._todos
는 private 변수로, 모든 할 일 항목을 저장합니다.addTodo
,toggleTodo
,deleteTodo
메서드는 상태를 변경하고notifyListeners()
를 호출하여 UI에 변경 사항을 알립니다.
5. Provider 설정하기
이제 main.dart
파일을 수정하여 Provider를 설정합니다:
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'models/todo_model.dart';
void main() {
runApp(
ChangeNotifierProvider(
create: (context) => TodoModel(),
child: MyApp(),
),
);
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Todo App',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: TodoListScreen(),
);
}
}
ChangeNotifierProvider
를 사용하여 TodoModel
을 앱의 최상위 레벨에서 제공합니다. 이렇게 하면 앱의 어느 위젯에서든 이 모델에 접근할 수 있게 됩니다.
6. UI 업데이트하기
이제 TodoListScreen
위젯을 수정하여 Provider를 사용하도록 만들어 봅시다:
class TodoListScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Todo List'),
),
body: Consumer<TodoModel>(
builder: (context, todoModel, child) {
return ListView.builder(
itemCount: todoModel.todos.length,
itemBuilder: (context, index) {
final todo = todoModel.todos[index];
return ListTile(
title: Text(todo.title),
leading: Checkbox(
value: todo.isCompleted,
onChanged: (_) => todoModel.toggleTodo(todo.id),
),
trailing: IconButton(
icon: Icon(Icons.delete),
onPressed: () => todoModel.deleteTodo(todo.id),
),
);
},
);
},
),
floatingActionButton: FloatingActionButton(
onPressed: () => _addTodo(context),
child: Icon(Icons.add),
),
);
}
void _addTodo(BuildContext context) {
showDialog(
context: context,
builder: (context) {
String newTodoTitle = '';
return AlertDialog(
title: Text('새 할 일 추가'),
content: TextField(
onChanged: (value) {
newTodoTitle = value;
},
),
actions: <Widget>[
TextButton(
child: Text('추가'),
onPressed: () {
if (newTodoTitle.isNotEmpty) {
Provider.of<TodoModel>(context, listen: false).addTodo(
Todo(id: DateTime.now().toString(), title: newTodoTitle),
);
Navigator.of(context).pop();
}
},
),
],
);
},
);
}
}
이 코드에 대해 자세히 설명하겠습니다:
Consumer<TodoModel>
을 사용하여TodoModel
의 변경 사항을 감지하고 UI를 업데이트합니다.ListView.builder
를 사용하여 할 일 목록을 효율적으로 표시합니다.- 각
ListTile
에서 체크박스와 삭제 버튼을 통해 할 일의 상태를 변경하거나 삭제할 수 있습니다. FloatingActionButton
을 눌러 새 할 일을 추가할 수 있습니다.
7. 새 할 일 추가 기능 구현하기
_addTodo
메서드는 다음과 같이 동작합니다:
- 사용자에게 새 할 일의 제목을 입력받는 대화 상자를 표시합니다.
- 사용자가 ‘추가’ 버튼을 누르면, 입력된 제목으로 새
Todo
객체를 생성합니다. Provider.of<TodoModel>(context, listen: false)
를 사용하여TodoModel
의 인스턴스를 가져옵니다.addTodo
메서드를 호출하여 새 할 일을 추가합니다.
마무리
이렇게 해서 Provider를 사용하여 To-Do 리스트 앱의 상태 관리를 개선해 보았습니다. 이제 앱의 상태가 중앙에서 관리되며, UI는 이 상태의 변화에 따라 자동으로 업데이트됩니다.
이러한 구조는 앱의 확장성을 크게 향상시키며, 새로운 기능을 추가하기 쉽게 만듭니다. 예를 들어, 할 일 항목 편집 기능이나 완료된 항목 필터링 기능 등을 쉽게 추가할 수 있습니다.
다음 포스팅에서는 이 앱에 데이터 지속성을 추가하여, 앱을 종료하고 다시 열어도 데이터가 유지되도록 만들어 보겠습니다.
Flutter와 Provider를 사용한 상태 관리에 대해 더 궁금한 점이 있다면 언제든 댓글로 남겨주세요. 함께 배우고 성장해 나가요!
관련 리소스
- Provider 패키지: https://pub.dev/packages/provider
- Flutter 상태 관리 문서: https://flutter.dev/docs/development/data-and-backend/state-mgmt
- Provider 공식 문서: https://pub.dev/documentation/provider/latest/
관련 포스팅
Flutter 개발-2: 프로젝트 생성 및 구조 파악 – CSAI
Flutter 개발-3: To-Do 리스트 앱 UI 구현하기 – CSAI
Flutter 개발-4: 앱 상태 관리 추가하기 – CSAI
Flutter 개발-5: 로컬 저장소 추가 – CSAI
Flutter 개발-6: 앱 UI 개선 및 기능 확장 – CSAI