- 해당 라이브러리를 플러터의
pubspec.yaml에 추가하여 준다.flutter pub add dio
picsum_model.dart
class PicsumModel {
final String id;
final String author;
final int width;
final int height;
final String url;
final String downloadUrl;
PicsumModel({
required this.id,
required this.author,
required this.width,
required this.height,
required this.url,
required this.downloadUrl,
});
}
- 무료 API 사이트 Lorem Picsum의 데이터 모델을 만들어 준다. 해당 객체 모델은 id, author, width, height, url, downloadUrl을 필드 값으로 가지고 있다.
class PicsumModel {
.
.
.
PicsumModel.fromJson(Map<String, dynamic> json)
: id = json["id"],
author = json["author"],
width = json["width"],
height = json["height"],
url = json["url"],
downloadUrl = json["download_url"];
factory PicsumModel.fromJson(Map<String, dynamic> json) {
return PicsumModel(
id: json["id"],
author: json["author"],
width: json["width"],
height: json["height"],
url: json["url"],
downloadUrl: json["download_url"],
);
}
.
.
.
}
- 해당 API 데이터를 가져올 때, json 형태의 구조를 앱에서 사용할 객체로 변환해야 한다.
picsum_repository.dart
import 'dart:convert';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'picsum_model.dart';
class PicsumRepository {
PicsumRepository._privateConstructor();
static final PicsumRepository _instance =
PicsumRepository._privateConstructor();
static PicsumRepository get instance => _instance;
Future<List<PicsumModel>> fetchData() async {
try {
final Dio dio = Dio();
int pageNumber = 1;
final response = await dio.get(
"https://picsum.photos/v2/list?page=$pageNumber&limit=10",
);
if (response.statusCode == 200) {
List<dynamic> data = response.data as List<dynamic>;
List<PicsumModel> result = data.map((element) {
return PicsumModel.fromJson(element);
}).toList();
return result;
} else {
return [];
}
} catch (error) {
debugPrint('[picsum_repository / _fetchData] $error');
return [];
}
}
}
- dio와 json을 이용하기 위해서
'dart:convert'와 'package:dio/dio.dart'를 import 해주었다.
- 해당 함수는 특정 페이지의 데이터를 가져오도록 구현하였고, 필요에 따라 해당
pageNumber 변수의 값에 변화를 주여 다른 페이지의 데이터를 가지고 올 수 있다.
- API 통신은 비동기 통신이기 때문에 async-await를 사용하여 비동기 처리를 해주어야 한다.
- 해당 예제에서는
Dio().get으로 GET 방식의 REST API를 호출하였다.
- URI를 사용하여 API호출을 하여 데이터를 가져왔고, 이에 대한 응답을
response 변수에 담아주었다.
- 해당
response의 상태 코드를 확인하여 정상(200)이면 데이터를 가지고 온다.
- 응답 받은
response의 body에 데이터가 있는데, 이는 json 형태이기에 앞서 PicsumModel에 정의해준 fromJson을 사용하여 PicsumModel로 데이터를 변환해준다.
picsum_view.dart
import 'package:flutter/material.dart';
import 'picsum_model.dart';
import 'picsum_repository.dart';
class PicsumView extends StatefulWidget {
const PicsumView({super.key});
@override
State<PicsumView> createState() => _PicsumViewState();
}
class _PicsumViewState extends State<PicsumView> {
List<PicsumModel> picsumModelList = [];
bool isLoading = false;
@override
void initState() {
initializeData();
super.initState();
}
Future<void> initializeData() async {
setState(() {
isLoading = true;
});
picsumModelList = await PicsumRepository.instance.fetchData();
setState(() {
isLoading = false;
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: isLoading
? const Scaffold(
body: Center(
child: CircularProgressIndicator(),
),
)
: Scaffold(
body: ListView.builder(
itemCount: picsumModelList.length,
itemBuilder: (BuildContext context, index) {
return picsumCardWidget(context, index);
},
),
),
);
}
Widget picsumCardWidget(context, int index) {
return Container(
height: MediaQuery.of(context).size.height * 0.15,
width: MediaQuery.of(context).size.width,
margin: EdgeInsets.symmetric(
vertical: MediaQuery.of(context).size.height * 0.01,
horizontal: MediaQuery.of(context).size.width * 0.03,
),
decoration: BoxDecoration(
color: Colors.grey[200],
borderRadius: BorderRadius.circular(16),
),
child: Row(
children: [
SizedBox(width: MediaQuery.of(context).size.width * 0.02),
ClipRRect(
borderRadius: BorderRadius.circular(16),
child: Image.network(
picsumModelList[index].downloadUrl,
height: MediaQuery.of(context).size.height * 0.13,
width: MediaQuery.of(context).size.height * 0.13,
fit: BoxFit.cover,
),
),
SizedBox(width: MediaQuery.of(context).size.width * 0.04),
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'ID : ${picsumModelList[index].id}',
style: const TextStyle(fontWeight: FontWeight.bold),
),
Text('Author : ${picsumModelList[index].author}'),
Text('Height : ${picsumModelList[index].height}'),
Text('Width : ${picsumModelList[index].width}'),
],
),
],
),
);
}
}
isLoading 변수는 데이터를 가지고 오는 동안에 로딩 화면을 띄어주기 위해 사용되었다.
picsumModelList 변수에 위에 PicsumRepository에서 정의한 fetchData를 사용하여 데이터를 가지고 왔다.
ListView.builder를 사용하여 picsumCardWidget의 형태로 화면을 나타냈다.
결과물
Ref.