Flutter 10주차 - dio 패키지를 이용해 reqres.in 사이트에서 API 정보 가져오기
2024. 11. 10. 19:42ㆍflutter
Flutter 10주차 - dio 패키지를 이용해 reqres.in 사이트에서 API 정보 가져오기
이번 주차에서는 reqres.in 사이트에서 제공하는 API를 사용해서 유저 정보 리스트를 구현할 예정이다.
dio 패키지 가져오기
이번 실습에서는 HTTP 요청을 처리할 수 있도록 하는 dio 패키지를 사용해서 구현할 예정이므로 pub.dev 에 들어가 dio 패키지를 설치하자.

설치 방법대로 dependencies 에 dio를 추가한 후

Pub get를 눌러 패키지를 설치하자.

reqres.in 유저 리스트 API 확인하기
https://reqres.in/api-docs/#/ 사이트에 들어가보면 reqres.in에서 제공하는 API들의 문서를 볼 수 있다.

우리가 사용할 유저 리스트 API에 대한 문서를 살펴보자.

해당 정보를 통해서 /users 의 경로로 page나 per_page param값을 담아 GET 요청을 보내면 사진과 같이 JSON 형식으로 유저들의 정보가 담겨온다는 것을 알 수 있다.
이제 이 정보를 통해서 코드를 작성해보자.
코드 작성하기
import 'package:flutter/material.dart'; // Flutter의 Material 디자인 패키지 가져오기
import 'package:dio/dio.dart'; // dio 패키지를 가져와서 HTTP 요청을 처리할 수 있도록 함
void main() {
runApp(MyApp()); // MyApp 위젯을 실행하여 앱 시작
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'User List', // 앱의 제목 설정
theme: ThemeData(
primarySwatch: Colors.blue, // 기본 색상 테마 설정
),
home: UserListScreen(), // 홈 화면으로 UserListScreen 위젯을 설정
);
}
}
class UserListScreen extends StatefulWidget {
const UserListScreen({super.key});
@override
State<UserListScreen> createState() => _UserListScreenState(); // 상태를 관리하는 클래스 생성
}
class _UserListScreenState extends State<UserListScreen> {
final Dio _dio = Dio(); // Dio 인스턴스를 생성하여 API 요청을 수행할 준비
List<dynamic> _users = []; // 사용자 데이터를 저장할 리스트
bool _isLoading = true; // 로딩 상태를 나타내는 변수
bool _isLoadingMore = false; // 추가 데이터 로딩 상태 변수
String _errorMessage = ''; // 오류 메시지를 저장할 변수
int _currentPage = 1; // 현재 페이지 번호
final ScrollController _scrollController = ScrollController(); // 스크롤 컨트롤러
@override
void initState() {
super.initState();
_fetchUsers(); // 초기 데이터를 불러오기
_scrollController.addListener(_scrollListener); // 스크롤 이벤트 리스너 추가
}
@override
void dispose() {
_scrollController.dispose(); // 위젯이 사라질 때 컨트롤러 해제
super.dispose();
}
// 스크롤 리스너 메서드
void _scrollListener() {
// 현재 스크롤 위치가 최하단일 경우 다음 페이지 데이터 불러오기
if (_scrollController.position.pixels == _scrollController.position.maxScrollExtent) {
_fetchMoreUsers();
}
}
// 사용자 데이터를 가져오는 비동기 메서드
Future<void> _fetchUsers() async {
try {
final response = await _dio.get('https://reqres.in/api/users?page=$_currentPage');
if (response.statusCode == 200) {
setState(() {
_users = response.data['data'];
_isLoading = false;
});
} else {
setState(() {
_errorMessage = '오류 발생: ${response.statusCode}';
_isLoading = false;
});
}
} on DioException catch (e) {
setState(() {
_errorMessage = '요청 중 오류 발생: $e';
_isLoading = false;
});
}
}
// 다음 페이지의 사용자 데이터를 추가로 가져오는 메서드
Future<void> _fetchMoreUsers() async {
if (_isLoadingMore) return; // 이미 추가 데이터를 로딩 중이면 실행하지 않음
setState(() {
_isLoadingMore = true; // 추가 데이터 로딩 상태를 true로 설정
});
try {
final response = await _dio.get('https://reqres.in/api/users?page=${_currentPage + 1}');
if (response.statusCode == 200) {
setState(() {
_currentPage++; // 페이지 번호 증가
_users.addAll(response.data['data']); // 새로운 데이터를 기존 리스트에 추가
_isLoadingMore = false; // 추가 데이터 로딩 상태를 false로 설정
});
} else {
setState(() {
_errorMessage = '오류 발생: ${response.statusCode}';
_isLoadingMore = false;
});
}
} on DioException catch (e) {
setState(() {
_errorMessage = '요청 중 오류 발생: $e';
_isLoadingMore = false;
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('사용자 목록'),
),
body: _isLoading
? Center(child: CircularProgressIndicator())
: _errorMessage.isNotEmpty
? Center(child: Text(_errorMessage))
: Column(
children: [
Expanded(
child: ListView.separated(
controller: _scrollController, // 스크롤 컨트롤러 설정
itemCount: _users.length,
separatorBuilder: (context, index) => Divider(),
itemBuilder: (context, index) {
final user = _users[index];
return ListTile(
contentPadding: EdgeInsets.symmetric(vertical: 20.0, horizontal: 16.0),
title: Text(user['first_name'] + ' ' + user['last_name']),
leading: CircleAvatar(
backgroundImage: NetworkImage(user['avatar']),
),
);
},
),
),
if (_isLoadingMore)
Padding(
padding: EdgeInsets.symmetric(vertical: 10),
child: CircularProgressIndicator(), // 추가 데이터를 로딩 중일 때 로딩 인디케이터 표시
),
],
),
);
}
}
실행 결과는 아래와 같다.


reqres.in에서 유저 정보 리스트를 불러와서 유저의 이름과 성, 아바타를 표시해주고 있다.
추가로 스크롤하면 다음 페이지의 유저 리스트 API 요청을 보내 계속해서 유저 정보가 보이도록 수정하였다.
'flutter' 카테고리의 다른 글
Flutter 12주차 - 플러터 앱과 파이어베이스 연동하기 (MacOS) (0) | 2024.11.23 |
---|---|
Flutter 11주차 - Youtube API를 이용한 동영상 플레이어 앱 (0) | 2024.11.19 |
Flutter 9주차 - 카카오 API를 이용해 도서 정보 가져오기 (3) | 2024.11.05 |
Flutter 중간시험 - 계산기 프로젝트 (0) | 2024.10.23 |
Flutter 7주차 (3) - 아이콘과 아이콘 버튼 활용하기 (1) | 2024.10.16 |