[Flutter] Retrofit 사용해보기 #2

이 글은 공식 문서와 유튜브 강의를 보고 배운 내용을 바탕으로 정리한 글입니다.

이전 글에서는 로컬에서 간단하게 연결해보았다. 유튜브 강의를 참고하여 공개되어있는 api를 이용해 실제 화면에 결과값을 출력해보자 마땅한 api를 찾지 못해 유트브 코드를 거의 그대로 작성했다...

코드작성

엔드포인트 설정

해커랭크 API를 이용했다 https://github.com/HackerNews/API

rest_client.dart

import 'package:dio/dio.dart';
import 'package:flutter_study/pages/retrofit/news.dart';
import 'package:retrofit/retrofit.dart';

part 'rest_client.g.dart';

(baseUrl: 'https://hacker-news.firebaseio.com/v0')
abstract class RestClient {
  factory RestClient(Dio dio, {String baseUrl}) = _RestClient;

  ('/beststories.json')
  Future<List<int>> getNewsIDs();

  ('/item/{id}.json')
  Future<News> getNewsDetail(() int id);
}
  • getNewsIDs: Get 요청으로 인기 뉴스 id 값들을 받아온다
  • getNewsDetail: Get요청으로 해당되는 id의 뉴스 데이터를 받아온다

news.dart

import 'package:json_annotation/json_annotation.dart';

part 'news.g.dart';

()
class News {
  int id;
  String title;
  String type;
  String url;

  News({
    required this.id,
    required this.title,
    required this.type,
    required this.url,
  });

  factory News.fromJson(Map<String, dynamic> json) => _$NewsFromJson(json);

  Map<String, dynamic> toJson() => _$NewsToJson(this);
}
  • 받아올 데이터들에 대한 모델 정의

출력 화면 작성

retrofit_screen.dart

import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter_study/pages/retrofit/news.dart';
import 'package:flutter_study/pages/retrofit/rest_client.dart';

class RetrofitScreen extends StatefulWidget {
  const RetrofitScreen({Key? key}) : super(key: key);

  
  _RetrofitScreenState createState() => _RetrofitScreenState();
}

class _RetrofitScreenState extends State<RetrofitScreen> {
  late RestClient client;
  Dio dio = Dio();

  
  void initState() {
    super.initState();
    client = RestClient(dio);
  }

  newsCard({
    required News news,
  }) {
    return Card(
      child: Column(
        children: [
          Text(news.id.toString()),
          Text(news.title),
          Text(news.type),
        ],
      ),
    );
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Retrofit'),
      ),
      body: FutureBuilder(
        future: client.getNewsIDs(),
        initialData: [],
        builder: (_, AsyncSnapshot snapshot) {
          if (snapshot.connectionState == ConnectionState.waiting) {
            return Center(
              child: CircularProgressIndicator(),
            );
          }

          final ids = snapshot.data;

          return ListView.builder(
            itemCount: ids.length,
            itemBuilder: (_, index) {
              return FutureBuilder(
                future: client.getNewsDetail(ids[index]),
                builder: (_, AsyncSnapshot snapshot) {
                  if (snapshot.connectionState == ConnectionState.waiting) {
                    return Center(
                      child: CircularProgressIndicator(),
                    );
                  }

                  return newsCard(news: snapshot.data);
                },
              );
            },
          );
        },
      ),
    );
  }
}
  • FutureBuilder를 이용해 결과값을 출력하도록 작성했다.

    FutureBuilder
    비동기 처리를 위한 위젯으로, future에는 요청 값, initialData에는 초기 값, builder에는 받아온 데이터를 바탕으로 위젯을 그릴 수 있다


    처음 인기 뉴스들의 ID값들을 받아오고, 받아온 ID를 통해 다시 한 번 요청을 해서 해당 뉴스들의 데이터를 받아오도록 작성했다. 즉 처음 바깥쪽 builder는 전체 ID에 대한 값을 기다리고, 안쪽의 builder는 각각 해당 뉴스에 대한 값을 기다린다.


결과화면

  • 처음 요청 화면은 인기 뉴스의 아이디를 받아온다
  • 두번째 요청 화면은 해당 아이디에 대한 각각의 뉴스 정보를 받아온다
  • 받아온 뉴스 정보를 리스트 형태로 보여준다.


Retrofit을 사용해 보았는데 편리한 기능들이 많이 있는 것 같다. 아직 다 사용해보진 못했지만 여러모로 편리한 기능들이 많이 들어가 있는 것 같다. 다만 작성할 코드가 많지 않다면 굳이 retrofit을 이용하는 것 보다는 직접 작성하는게 더 나아보인다. 하지만 거의 귀찮아서 사용할 것 같다...
그건 그렇고 이미지 크기가 왜 안 바뀌는지 모르겠다. 미리보기에서는 잘 바뀌고 정렬도 되는데 수정만 하면 이미지가 그대로 올라가버린다. 구글링을 해도 도무지 이유를 모르겠다...얼른 수정해야 되는데

이미지를 합쳐서 합친 이미지를 한번에 첨부했다. 매번 이렇게 해야 되는지는 모르겠네...


참고링크

좋은 웹페이지 즐겨찾기