-->

Tutorial Android dengan Retrofit HTTP Library

Hai, pada artikel sebelumnya yang berjudul Android Grid RecyclerVew dan Menampilkan Gambar dengan Picasso, telah dijelaskan cara membuat aplikasi android yang menampilkan data dengan grid layout menggunakan RecyclerView. Pada artikel tersebut juga diterangkan cara untuk menampilkan data dengan menggunakan library Picasso. Dan kali ini, akan dijelaskan cara menggunakan Retrofit di dalam aplikasi untuk mengambil json dan menampilkan data ke aplikasi.


Retrofit adalah library android yang dibuat oleh Squre yang digunakan sebagai REST Client pada Android, yang pasti akan memudahkan kita dalam programing. Karena kita tidak perlu lagi untuk membuat method-method sendiri untuk menggunakan REST Client API dari backend. Library ini menyediakan framework yang powerfull untuk authenticating dan berinteraksi dengan API dengan mengirimkan request menggunakan OkHTTP.

Menyiapkan API

Pada artikle ini kita akan menggunakan API dari sebuah website bernama The Movie DB, website penyedia informasi tentang film dan juga menyediakan API secara gratis dengan syarat harus register terlebih dahulu.

Untuk mendapatkan API, masuk ke website tersebut, lalu pilih Sign Up. Selanjutnya masuk ke akun, lalu pilih menu API dan lakukan langkah sesuai dengan yang dibituhkan, jika sudah maka akan tampil data seperti ini


Membuat Project Baru

Pertama buat project baru dengan nama Retrofit HTTP Library. Pilih empty activity pada pilihan activity.

Membuat Request Pertama

Menginstal Library

Untuk menggunakan Retrofit, kiata harus menginstal terlebih dahulu library Retrofit dan library Gson. Library gson sendiri adalah library yang dilincurkan oleh Google untuk memparsing data json.

Buka build:grandle dan masukkan kode berikut ini, setelah itu pilih sync project


dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:24.0.0'
    // retrofit, gson
    compile 'com.google.code.gson:gson:2.6.2'
    compile 'com.squareup.retrofit2:retrofit:2.0.2'
    compile 'com.squareup.retrofit2:converter-gson:2.0.2'
    compile 'com.android.support:recyclerview-v7:24.0.0'
}


Membuat Model

Pertama, kita harus mengetahui tipe respon json yang akan kita terima. Buka link berikut ini http://api.themoviedb.org/3/movie/top_rated?api_key=(api sobat). Maka kita akan mendapatkan 50 data film. Gunakan JsonViewer untuk melihat struktur json. Setelah dibuka, salin seluruh data yang tampil ke dalam JsonViewer dan pilih tab Viewer. Dari situ kita bisa melihat struktur data seperti field dan parent data yang nantinya akan kita panggil dalam aplikasi ini



Masuk ke aplikasi Android Studio, klik kanan dan tambahkan package baru dengan nama Model, kemudian buat class baru dengan nama Movie.java dan buat kodenya seperti berikut ini


package com.blogsetyaaji.retrofithttplibrary.Model;

import com.google.gson.annotations.SerializedName;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by AJISETYA
 */
public class Movie {

    @SerializedName("poster_path")
    private String posterPath;
    @SerializedName("adult")
    private boolean adult;
    @SerializedName("overview")
    private String overview;
    @SerializedName("release_date")
    private String releaseDate;
    @SerializedName("genre_ids")
    private List<Integer> genreIds = new ArrayList<Integer>();
    @SerializedName("id")
    private Integer id;
    @SerializedName("original_title")
    private String originalTitle;
    @SerializedName("original_language")
    private String originalLanguage;
    @SerializedName("title")
    private String title;
    @SerializedName("backdrop_path")
    private String backdropPath;
    @SerializedName("popularity")
    private Double popularity;
    @SerializedName("vote_count")
    private Integer voteCount;
    @SerializedName("video")
    private Boolean video;
    @SerializedName("vote_average")
    private Double voteAverage;

    public Movie(String posterPath, boolean adult, String overview, String releaseDate, List<Integer> genreIds, Integer id,
                 String originalTitle, String originalLanguage, String title, String backdropPath, Double popularity,
                 Integer voteCount, Boolean video, Double voteAverage) {
        this.posterPath = posterPath;
        this.adult = adult;
        this.overview = overview;
        this.releaseDate = releaseDate;
        this.genreIds = genreIds;
        this.id = id;
        this.originalTitle = originalTitle;
        this.originalLanguage = originalLanguage;
        this.title = title;
        this.backdropPath = backdropPath;
        this.popularity = popularity;
        this.voteCount = voteCount;
        this.video = video;
        this.voteAverage = voteAverage;
    }

    public Double getVoteAverage() {
        return voteAverage;
    }

    public void setVoteAverage(Double voteAverage) {
        this.voteAverage = voteAverage;
    }

    public String getPosterPath() {
        return posterPath;
    }

    public void setPosterPath(String posterPath) {
        this.posterPath = posterPath;
    }

    public boolean isAdult() {
        return adult;
    }

    public void setAdult(boolean adult) {
        this.adult = adult;
    }

    public String getOverview() {
        return overview;
    }

    public void setOverview(String overview) {
        this.overview = overview;
    }

    public String getReleaseDate() {
        return releaseDate;
    }

    public void setReleaseDate(String releaseDate) {
        this.releaseDate = releaseDate;
    }

    public List<Integer> getGenreIds() {
        return genreIds;
    }

    public void setGenreIds(List<Integer> genreIds) {
        this.genreIds = genreIds;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getOriginalTitle() {
        return originalTitle;
    }

    public void setOriginalTitle(String originalTitle) {
        this.originalTitle = originalTitle;
    }

    public String getOriginalLanguage() {
        return originalLanguage;
    }

    public void setOriginalLanguage(String originalLanguage) {
        this.originalLanguage = originalLanguage;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getBackdropPath() {
        return backdropPath;
    }

    public void setBackdropPath(String backdropPath) {
        this.backdropPath = backdropPath;
    }

    public Double getPopularity() {
        return popularity;
    }

    public void setPopularity(Double popularity) {
        this.popularity = popularity;
    }

    public Integer getVoteCount() {
        return voteCount;
    }

    public void setVoteCount(Integer voteCount) {
        this.voteCount = voteCount;
    }

    public Boolean getVideo() {
        return video;
    }

    public void setVideo(Boolean video) {
        this.video = video;
    }
}


Di dalam class Moview, fild dala data json dideklarasikan dan dijadikan variable untuk diproses di dalam aplikasi. Dalam class tersebut juga menggunakan getter dan setter untuk mengatur dan mendapatkan data.

Selanjutnya buat class baru dengan nama MoviewResponse.java. Class ini digunakan untuk mendapatkan data tambahan yang nanatinya dibutuhkan dalam aplaikasi. Untuk kodenya seperti berikut ini


package com.blogsetyaaji.retrofithttplibrary.Model;

import com.google.gson.annotations.SerializedName;

import java.util.List;

/**
 * Created by AJISETYA
 */
public class MovieResponse {

    @SerializedName("page")
    private int page;
    @SerializedName("results")
    private List<Movie> results;
    @SerializedName("total_results")
    private int totalResults;
    @SerializedName("total_pages")
    private int totalPages;

    public int getTotalPages() {
        return totalPages;
    }

    public void setTotalPages(int totalPages) {
        this.totalPages = totalPages;
    }

    public int getPage() {
        return page;
    }

    public void setPage(int page) {
        this.page = page;
    }

    public List<Movie> getResults() {
        return results;
    }

    public void setResults(List<Movie> results) {
        this.results = results;
    }

    public int getTotalResults() {
        return totalResults;
    }

    public void setTotalResults(int totalResults) {
        this.totalResults = totalResults;
    }


}


Membuat Instansi Retrofit

Kita membutuhkan Retrofit Builder dan URL dasar. Maka buat package baru dengan nama Rest, dan buat class baru dengan nama ApiClient.java, kemudian buat kodenya seperti berikut ini


package com.blogsetyaaji.retrofithttplibrary.Rest;

import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

/**
 * Created by AJISETYA
 */
public class ApiClient {

    public static final String BASE_URL = "http://api.themoviedb.org/3/";
    private static Retrofit retrofit = null;


    public static Retrofit getClient() {
        if (retrofit==null) {
            retrofit = new Retrofit.Builder()
                    .baseUrl(BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();
        }
        return retrofit;
    }
}



Mendefinisikan Endpoints

Endpoint didefinisikan di dalam interface menggunakan anotasi spesial retrofit untuk untuk mengkodekan rincian tentang parameter dan metode permintaan.

Buat Interface baru dengan nama ApiInterface.java di dalam package Rest dan buat kodenya seperti berikut


package com.blogsetyaaji.retrofithttplibrary.Rest;

import com.blogsetyaaji.retrofithttplibrary.Model.MovieResponse;

import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Path;
import retrofit2.http.Query;

/**
 * Created by AJISETYA
 */
public interface ApiInterface {
    @GET("movie/top_rated")
    Call<MovieResponse> getTopRatedMovies(@Query("api_key") String apiKey);

    @GET("movie/{id}")
    Call<MovieResponse> getMovieDetails(@Path("id") int id, @Query("api_key") String apiKey);
}



Setiap EndPoint menentukan anotasi dari method HTTP (GET, POST, dll) dan parameter dari method ini juga memiliki anotasi spesial (@Query, @Path, @Body, dll)

Memangil Permintaan Pertama

Buka MainActivity.java dan buat kodenya menjadi seperti di bawah ini. Jangan lupa masukkan Api ilik sobat.


package com.blogsetyaaji.retrofithttplibrary;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;

import com.blogsetyaaji.retrofithttplibrary.Model.Movie;
import com.blogsetyaaji.retrofithttplibrary.Model.MovieResponse;
import com.blogsetyaaji.retrofithttplibrary.Rest.ApiClient;
import com.blogsetyaaji.retrofithttplibrary.Rest.ApiInterface;

import java.util.List;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

public class MainActivity extends AppCompatActivity {

    private static final String TAG = MainActivity.class.getSimpleName();

    // TODO - insert your themoviedb.org API KEY here
    private final static String API_KEY = "api key kamu";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (API_KEY.isEmpty()) {
            Toast.makeText(getApplicationContext(), "Please obtain your API KEY first from themoviedb.org", Toast.LENGTH_LONG).show();
            return;
        }

        ApiInterface apiService =
                ApiClient.getClient().create(ApiInterface.class);

        Call<MovieResponse> call = apiService.getTopRatedMovies(API_KEY);
        call.enqueue(new Callback<MovieResponse>() {
            @Override
            public void onResponse(Call<MovieResponse>call, Response<MovieResponse> response) {
                List<Movie> movies = response.body().getResults();
                Log.d(TAG, "Number of movies received: " + movies.size());
                Toast.makeText(MainActivity.this, "Number of movies received: " + movies.size(), Toast.LENGTH_LONG).show();
            }

            @Override
            public void onFailure(Call<MovieResponse>call, Throwable t) {
                // Log error here since request failed
                Log.e(TAG, t.toString());
            }
        });
    }
}


Retrofit akan mendownload dan memparsing data API dan mengembalikan ke User Interface lewat metode onResponse dan onFailure. Tapi sebelum menjalankan aplikasi, terlebih dahulu beri izin akses internet pada AndroidManifest.xml seperti kode di bawah ini


<uses-permission android:name="android.permission.INTERNET"/>


Jalankan aplikasi dengan memilih menu Run 'app', hasilnya akan seperti berikut


Dan itu adalah percobaan pertama untuk mengetes apakah permintaan bisa diproses pada tahap selanjutnya. Sekarang kita akanmelakukan langkah selanjutnya yaitu menampilkan data dari web The Movie Db. Berikut langkah-langkahnya.

Menampilkan Data di RecyclerView

Selain kita menampilkan data di RecyclerView, kita juga akan menampilkan gambar di library Picasso. Jadi untuk pertama kali, kita lakukan langkah di bawah ini

Menambah Dependencies

Tambahkan dependencies baru di dalam build:grandle untuk menambah library recyclerview dan picasso. Kodenya seperti berikut ini


compile 'com.android.support:recyclerview-v7:24.0.0'
compile 'com.squareup.picasso:picasso:2.3.2'


Membuat Tampilan

Buka color.xml dan tambahkan kode hingga menjadi seperti di bawah ini untuk menambah warna yang nantinya akan ditampilkan.


<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#3F51B5</color>
    <color name="colorPrimaryDark">#303F9F</color>
    <color name="colorAccent">#FF4081</color>

    <color name="orange">#FF3909</color>
    <color name="colorAccentDark">#00B482</color>

    <color name="colorBlack">#555555</color>
    <color name="colorWhite">#FFFFFF</color>
    <color name="colorGrey">#707070</color>
    <color name="colorGreyLight">#8A8A8A</color>
</resources>


Selanjutnya kita buat gambar bintang untuk menunjukka rate dari film. Buat layout baru di dalam folder drawable dengan nama star.xml dan buat kodenya seperti berikut ini



<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="24dp"
    android:height="24dp"
    android:viewportHeight="24"
    android:viewportWidth="24">
    <path
        android:fillColor="#000"
        android:pathData="M12,17.27L18.18,21L16.54,13.97L22,9.24L14.81,8.62L12,2L9.19,8.62L2,9.24L7.45,13.97L5.82,21L12,17.27Z" />
</vector>


Kita butuh layout untuk menampng informasi yang akan ditampilkan. Kita membutuhkan 4 TextView dan dua ImageView dalam layout tersebut. Buat layout baru dengan nama list_item_movie.xml dan buat kodenya seperti berikut ini


<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/movies_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center_vertical"
    android:minHeight="72dp"
    android:orientation="horizontal"
    android:padding="16dp">

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/backbg"
        android:layout_marginRight="7dp"/>

    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:orientation="vertical">

        <TextView
            android:id="@+id/title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="top"
            android:paddingRight="16dp"
            android:textStyle="bold"
            android:textColor="@color/colorBlack"
            android:textSize="16sp" />


        <TextView
            android:id="@+id/subtitle"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:paddingRight="16dp"
            android:textColor="@color/colorGreyLight" />

        <TextView
            android:id="@+id/description"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:maxLines="3"
            android:paddingRight="16dp"
            android:textColor="@color/colorGreyLight" />

    </LinearLayout>

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="35dp"
        android:orientation="horizontal">

        <ImageView
            android:id="@+id/rating_image"
            android:layout_width="15dp"
            android:layout_height="15dp"
            android:layout_centerInParent="true"
            android:scaleType="centerCrop"
            android:src="@drawable/star"
            android:tint="@color/colorAccent" />


        <TextView
            android:id="@+id/rating"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="8dp"
            android:text="5.0" />
    </LinearLayout>

</LinearLayout>


Tambahkan objek RecyclerViewada di dalam activity_main.xml dengan membuat kodenya seperti berikut ini


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.blogsetyaaji.retrofithttplibrary.MainActivity">

    <android.support.v7.widget.RecyclerView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/movie_recycler"/>
</RelativeLayout>


Membuat Adapter

RecylerView membutuhkan adapter yang berfungsi untuk melihat, mengikat, dan memproses data. Untuk membuatnya, buat class baru dengan nama MovieAdapter.java di dalam package Adapter dan buat kodenya seperti berikut ini


package com.blogsetyaaji.retrofithttplibrary.Adapter;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.blogsetyaaji.retrofithttplibrary.Model.Movie;
import com.blogsetyaaji.retrofithttplibrary.R;
import com.squareup.picasso.Picasso;

import java.util.List;

/**
 * Created by AJISETYA
 */
public class MoviesAdapter extends RecyclerView.Adapter<MoviesAdapter.MovieViewHolder> {

    private List<Movie> movies;
    private int rowLayout;
    private Context context;


    public static class MovieViewHolder extends RecyclerView.ViewHolder {
        LinearLayout moviesLayout;
        TextView movieTitle;
        TextView data;
        TextView movieDescription;
        TextView rating;
        ImageView backbg;


        public MovieViewHolder(View v) {
            super(v);
            moviesLayout = (LinearLayout) v.findViewById(R.id.movies_layout);
            movieTitle = (TextView) v.findViewById(R.id.title);
            data = (TextView) v.findViewById(R.id.subtitle);
            movieDescription = (TextView) v.findViewById(R.id.description);
            rating = (TextView) v.findViewById(R.id.rating);
            backbg = (ImageView) v.findViewById(R.id.backbg);
        }
    }

    public MoviesAdapter(List<Movie> movies, int rowLayout, Context context) {
        this.movies = movies;
        this.rowLayout = rowLayout;
        this.context = context;
    }

    @Override
    public MoviesAdapter.MovieViewHolder onCreateViewHolder(ViewGroup parent,
                                                            int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(rowLayout, parent, false);
        return new MovieViewHolder(view);
    }


    @Override
    public void onBindViewHolder(MovieViewHolder holder, final int position) {
        holder.movieTitle.setText(movies.get(position).getTitle());
        holder.data.setText(movies.get(position).getReleaseDate());
        holder.movieDescription.setText(movies.get(position).getOverview());
        holder.rating.setText(movies.get(position).getVoteAverage().toString());
        Picasso.with(context).load("https://image.tmdb.org/t/p/w300_and_h450_bestv2" + movies.get(position).getBackdropPath()).resize(200, 250).into(holder.backbg);
    }

    @Override
    public int getItemCount() {
        return movies.size();
    }
}


Di dalam kode adapter di atas, terdapat satu baris kode picasso untuk menampilkan gambar dari sumber API dengan mengunakan tambahan link dasar.

Membuat Activity

Sekarang buka MainActivity.java untuk menambahkan data ke activity objek RecyclerView. Buat kodenya seperti berikut ini


package com.blogsetyaaji.retrofithttplibrary;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.widget.Toast;

import com.blogsetyaaji.retrofithttplibrary.Adapter.MoviesAdapter;
import com.blogsetyaaji.retrofithttplibrary.Model.Movie;
import com.blogsetyaaji.retrofithttplibrary.Model.MovieResponse;
import com.blogsetyaaji.retrofithttplibrary.Rest.ApiClient;
import com.blogsetyaaji.retrofithttplibrary.Rest.ApiInterface;

import java.util.List;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

public class MainActivity extends AppCompatActivity {

    private static final String TAG = MainActivity.class.getSimpleName();

    // TODO - insert your themoviedb.org API KEY here
    private final static String API_KEY = "api key kamu";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (API_KEY.isEmpty()) {
            Toast.makeText(getApplicationContext(), "Please obtain your API KEY first from themoviedb.org", Toast.LENGTH_LONG).show();
            return;
        }

        final RecyclerView recyclerView = (RecyclerView) findViewById(R.id.movie_recycler);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));

        ApiInterface apiService =
                ApiClient.getClient().create(ApiInterface.class);

        Call<MovieResponse> call = apiService.getTopRatedMovies(API_KEY);
        call.enqueue(new Callback<MovieResponse>() {
            @Override
            public void onResponse(Call<MovieResponse>call, Response<MovieResponse> response) {
                List<Movie> movies = response.body().getResults();
                Log.d(TAG, "Number of movies received: " + movies.size());
                Toast.makeText(MainActivity.this, "Number of movies received: " + movies.size(), Toast.LENGTH_LONG).show();
                recyclerView.setAdapter(new MoviesAdapter(movies, R.layout.list_item_movie, getApplicationContext()));
            }

            @Override
            public void onFailure(Call<MovieResponse>call, Throwable t) {
                // Log error here since request failed
                Log.e(TAG, t.toString());
            }
        });
    }
}

Menjalankan Aplikasi

Setelah semuanya selesai, saatnya menjalankan aplikais dengan memilih menu Run 'app'. Tampilanya akan seperti berikut ini



SIlahkan jika sobat ingin melihat hasil projectnya di github saya

Follow @AjiSetya Watch Star

Data telah berhasil ditampilkan, mungki sobat bisa menambahkan CardView untuk mempercantik tampilanya.
Oiya kalau sobat pengen menambahkan aksi ketika datanya diklik, sobat bisa buka artkel di bawah ini.

Membuat Klik pada RecyclerView Menggunakan OnClick Listener / ItemClick Listener

Sekian artikel tentang Tutorial Android dengan Retrofit HTTP Library. semoga bermanfaat. Ikuti terus Blog Setya Aji dan nanikan artikel menarik lainya.


Previous
Next Post »
Load comments