목차
- MVVM 패턴
- MVVM 패턴이란?
- MVVM 패턴 구조
- 사용된 기능 설명
- 사용 예시
✅ MVVM 패턴
- MVVM 패턴이란?
- MVVM은 Model-View-ViewModel의 약자로, UI와 비즈니스 로직을 깔끔하게 분리하는 패턴
- MVVM 패턴 구조
- Model: 데이터 구조와 변환 (= 데이터 설계)
- DataSource: 실제 데이터 소스 접근(API/DB)
- Repository: 데이터 저장소로, DataSource와 ViewModel 중계
- ViewModel: View의 상태 관리, 데이터 가공 등 View의 비즈니스 로직을 담당
- View: 화면 표시, 사용자 이벤트 처리, ViewModel 구독
✅ 사용된 기능 설명
- ChangeNotifierProvider : Provider 패키지에서 제공하는 상태 제공자. ChangeNotifier를 생성하고, 하위 위젯 트리에서 접근 가능하도록 제공
- Consumer<T> : Provider에서 제공한 데이터를 구독하는 위젯으로 상태가 바뀌면 자동으로 rebuild. 특정 타입(T)의 Provider만 구독 가능
- notifyListeners() : ChangeNotifier를 상속한 ViewModel 클래스에서 상태가 바뀌었음을 구독자(View)에 알림.
이를 통해 Flutter의 UI를 자동으로 다시 그리게(rebuild) 함
✅ 사용 예시
1️⃣ model

2️⃣ dataSource

3️⃣ repository

4️⃣ viewModel

5️⃣ view

6️⃣ 테스트
- HTTP 에서 JSON 데이터 받아올 때, iOS 정책에 의해 에러 발생
- chrome으로 실행 시, 데이터 정상 작동


✔️ 사용된 코드
1️⃣ model
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']);
}
}
2️⃣ dataSource
import 'dart:convert';
import 'package:http/http.dart' as http;
import '../model/album.dart';
class DataSource {
Future<List<Album>> getAlbumList() async {
final response = await http
.get(Uri.parse('https://jsonplaceholder.typicode.com/albums'));
return jsonDecode(response.body)
.map<Album>((json) => Album.fromJson(json)).toList();
}
}
3️⃣ repository
import '../dataSource/dataSource.dart';
import '../model/album.dart';
class AlbumRepository{
final DataSource _dataSource = DataSource();
Future<List<Album>> getAlbumList(){
return _dataSource.getAlbumList();
}
}
4️⃣ viewModel
import 'package:flutter/material.dart';
import '../model/album.dart';
import '../repository/albumRepository.dart';
class AlbumViewModel with ChangeNotifier{
late final AlbumRepository _albumRepository;
List<Album> _albumList = List.empty(growable: true);
List<Album> get albumList => _albumList;
AlbumViewModel(){
_albumRepository = AlbumRepository();
_getAlbumList();
}
Future<void> _getAlbumList() async{
_albumList = await _albumRepository.getAlbumList();
notifyListeners(); // ChangeNotifier를 상속한 ViewModel 클래스에서 상태가 바뀌었음을 View에 알림
}
}
5️⃣ view
import "package:flutter/material.dart";
import "package:provider/provider.dart";
import "../model/album.dart";
import "../viewModel/albumViewModel.dart";
class AlbumView extends StatefulWidget {
const AlbumView({super.key});
@override
State<AlbumView> createState() => _AlbumViewState();
}
class _AlbumViewState extends State<AlbumView> {
late List<Album> albumList;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("MVVM 실습"),
),
body: Consumer<AlbumViewModel>( // Consumer<T> : Provider에서 제공한 데이터를 구독하는 위젯으로 상태가 바뀌면 자동으로 rebuild. 특정 타입(T)의 Provider만 구독 가능
builder: (context, provider, child){
albumList = provider.albumList;
return ListView.builder(
itemCount: albumList.length,
itemBuilder: (context, index){
return Container(
padding: const EdgeInsets.all(15),
child: Text("${albumList[index].id} : ${albumList[index].title}"),
);
}
);
}
)
);
}
}
'IT 언어 > Flutter' 카테고리의 다른 글
| [Flutter] Carousel Silder (자동 슬라이드) [맥북💻] (0) | 2025.10.03 |
|---|---|
| [Flutter] ListView 페이지 스크롤 [맥북💻] (0) | 2025.09.30 |
| [Flutter] Form 양식 제출 (GlobalKey, TextFormField, ModalRoute) [맥북💻] (0) | 2025.09.29 |
| [Flutter] 웹뷰 (webview_flutter) [맥북💻] (0) | 2025.09.28 |
| [Flutter] 푸시 알림 보내기 (Local Notifications) [맥북💻] (0) | 2025.09.28 |