Provider 패턴은 Flutter 애플리케이션에서 상태 관리를 효율적으로 수행하기 위해 사용되는 패턴입니다. 이 패턴은 InheritedWidget을 기반으로 하며, 상태를 위젯 트리에서 쉽게 공유하고 관리할 수 있게 도와줍니다. Provider 패턴은 Flutter의 공식 상태 관리 솔루션 중 하나로, 단순하고 강력한 상태 관리 방법을 제공합니다.
주요 개념
1. Provider:
• 상태를 제공하는 역할을 합니다. Provider는 다양한 유형이 있으며, ChangeNotifierProvider, Provider, FutureProvider, StreamProvider 등이 있습니다.
2. ChangeNotifier:
• 상태 변경을 알리기 위해 사용되는 클래스입니다. ChangeNotifier를 상속받아 상태를 관리하고, notifyListeners()를 호출하여 리스너들에게 상태 변경을 알립니다.
3. Consumer:
• Provider에서 제공하는 상태를 구독하고, 상태가 변경될 때마다 UI를 업데이트하는 역할을 합니다.
Provider의 유형
1. ChangeNotifierProvider:
• ChangeNotifier를 사용하여 상태를 제공하고 관리합니다.
2. Provider:
• 기본적인 상태 제공자로, 변경되지 않는 데이터를 제공할 때 사용합니다.
3. FutureProvider:
• 비동기 작업의 결과를 제공하는 Provider입니다.
4. StreamProvider:
• 스트림 데이터를 제공하는 Provider입니다.
예제: ChangeNotifierProvider 사용
간단한 카운터 애플리케이션을 Provider 패턴으로 구현한 예제를 살펴보겠습니다.
dependencies 에 추가
provider:
모델 클래스
import 'package:flutter/foundation.dart';
class Counter with ChangeNotifier {
int _count = 0;
int get count => _count;
void increment() {
_count++;
notifyListeners();
}
void decrement() {
_count--;
notifyListeners();
}
}
메인 애플리케이션
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'counter.dart'; // Counter 모델 클래스 가져오기
void main() {
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => Counter()),
],
child: MyApp(),
),
);
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: CounterPage(),
);
}
}
class CounterPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
final counter = Provider.of<Counter>(context);
return Scaffold(
appBar: AppBar(
title: Text('Provider Counter Example'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'Counter: ${counter.count}',
style: TextStyle(fontSize: 24),
),
],
),
),
floatingActionButton: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
FloatingActionButton(
onPressed: counter.increment,
child: Icon(Icons.add),
),
SizedBox(height: 10),
FloatingActionButton(
onPressed: counter.decrement,
child: Icon(Icons.remove),
),
],
),
);
}
}
주요 구성 요소
1. Counter 모델 클래스:
• ChangeNotifier를 상속받아 상태를 관리합니다.
• increment와 decrement 메서드를 통해 상태를 변경하고, notifyListeners()를 호출하여 리스너에게 상태 변경을 알립니다.
2. MultiProvider:
• 여러 Provider를 동시에 제공할 때 사용합니다. 이 예제에서는 ChangeNotifierProvider를 사용하여 Counter 상태를 제공합니다.
3. Provider.of(context):
• 현재 컨텍스트에서 Provider가 제공하는 상태를 구독합니다. 여기서는 Counter 상태를 구독하여 카운터 값을 업데이트합니다.
4. FloatingActionButton:
• onPressed 콜백에서 counter.increment와 counter.decrement를 호출하여 카운터 값을 증가 및 감소시킵니다.
다른 예시(실습)
필요 파일
provider 패키지
- album_provider.dart
model 패키지
- album.dart
view 패키지
- album_provider_view.dart
album.dart
class Album {
int? userId;
int? id;
String? title;
Album({this.userId, this.id, this.title});
factory Album.fromJson(Map<String, dynamic> json) {
return Album(
userId: json['userId'],
id: json['id'],
title: json['title'],
);
}
}
album_provider.dart
import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:http/http.dart' as http;
import '../model/album.dart';
class AlbumProvider with ChangeNotifier {
final List<Album> _albumList = List.empty(growable: true);
List<Album> getAlbumList() {
_fetchAlbums();
return _albumList;
}
void _fetchAlbums() async {
final response = await http.get(Uri.parse("https://jsonplaceholder.typicode.com/albums"));
final List<Album> result = jsonDecode(response.body)
.map<Album>((json) => Album.fromJson(json))
.toList();
_albumList.clear();
_albumList.addAll(result);
notifyListeners();
}
}
album_provider_view.dart
import 'package:flutter/material.dart';
import 'package:flutter_lecture/provider/album_provider.dart';
import 'package:provider/provider.dart';
import '../model/album.dart';
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
late List<Album> albumList;
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider<AlbumProvider>(
create: ((context) => AlbumProvider()),
child: Scaffold(
appBar: AppBar(
title: const Text("test title"),
),
body: Consumer<AlbumProvider>(
builder: (context, provider, child) {
albumList = provider.getAlbumList();
return ListView.builder(
itemCount: albumList.length,
itemBuilder: (context, index) {
return Container(
padding: const EdgeInsets.all(10),
child: Text("${albumList[index].id} : ${albumList[index].title}"),
);
}
);
},
),
),
);
}
}
Provider 패턴의 장점
1. 단순성:
• Provider 패턴은 Flutter의 상태 관리 솔루션 중 가장 단순하면서도 강력한 패턴입니다.
2. 유연성:
• 다양한 유형의 Provider를 제공하여 다양한 상태 관리 요구를 충족할 수 있습니다.
3. 성능 최적화:
• Provider는 효율적으로 상태를 구독하고 업데이트하여 성능을 최적화합니다.
4. 재사용성:
• 상태와 비즈니스 로직을 별도의 클래스로 분리하여 재사용성을 높입니다.
참고 문서
이 정보를 통해 Flutter 애플리케이션에서 Provider 패턴을 효과적으로 사용하여 상태 관리를 수행할 수 있습니다. Provider 패턴을 활용하면 코드의 구조를 개선하고 유지보수성을 높일 수 있습니다.
'프론트엔드 > Flutter' 카테고리의 다른 글
flutter local notifications - 알림 (0) | 2024.07.22 |
---|---|
flutter get_it 패턴 (1) | 2024.07.22 |
flutter bloc 패턴 적용 (0) | 2024.07.22 |
flutter 리프레쉬 인디케이터 (0) | 2024.07.22 |
dart 반복문 정리 (0) | 2024.07.21 |