Bootcamp Week 5

2. Client Server ( Get )

1. Retrofit

Sabtu, 16 Maret 2019

05 Jan 2019

12 Jan 2019

19 Jan 2019

26 Jan 2019

Bootcamp 16 Feb - 20 April 2019

Kopibar

Kedai Ekspresi

Dilo Depok

Keboen Koding

Bootcamp

REST API Client dengan Retrofit pada Android Studio

Retrofit

Retrofit adalah library Rest Client untuk android dan java dari squareup.

Volley

merupakan produk yang diperkenalkan oleh Google untuk mempermudah pertukaran data tanpa harus membuat deretan kode yang sangat panjang.

Fast Android Networking

 library ini memiliki banyak fitur yang tidak ada di library Retrofit. Dan tentunya lebih lengkap dibandingkan Retrofit maupun volley.

Materi Sebelumnya

REST API

Permission Internet di File Manifest

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

Permission Internet kita tambahkan agar aplikasi bisa berkomunikasi dengan internet atau menggunakan sumber internet yang tersedia pada handphone.

Menambahkan Depedensi di Gradle

    implementation 'com.squareup.retrofit2:retrofit:2.5.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.5.0'

Retrofit => untuk proses membantu pengambilan data json REST API.

GSON => library untuk mengubah JSON menjadi Object. Dengan menggunakan ini kita tidak perlu lagi set get data ke dalam Model secara manual tapi langsung dikerjanan oleh GSON.

Tambahkan Package baru dengan nama : network

Menjadi

Klik Kanan -> New -> Package

Buat Java Class : ApiClient 

 

Klik Kanan > New > Java Class

package com.meetap.tontonan.network;

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

public class ApiClient {

    //Membuat method return untuk mendapatkan retrofit yang sudah berisi base url
    public static Retrofit getClient() {

        return new Retrofit.Builder()
                .baseUrl("http://malea.id/")
                .addConverterFactory(GsonConverterFactory.create())
                .build();

    }
}

Buat Package : resApi

Buat didalamnya Class : DataItem

Class : DataItem

package com.meetap.tontonan.model.resApi;

import com.google.gson.annotations.SerializedName;

public class DataItem {

    @SerializedName("genre")
    private String genre;

    @SerializedName("rilis")
    private String rilis;

    @SerializedName("id")
    private String id;

    @SerializedName("video")
    private String video;

    @SerializedName("title")
    private String title;

    @SerializedName("durasi")
    private String durasi;

    public void setGenre(String genre) {
        this.genre = genre;
    }

    public String getGenre() {
        return genre;
    }

    public void setRilis(String rilis) {
        this.rilis = rilis;
    }

    public String getRilis() {
        return rilis;
    }

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

    public String getId() {
        return id;
    }

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

    public String getVideo() {
        return video;
    }

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

    public String getTitle() {
        return title;
    }

    public void setDurasi(String durasi) {
        this.durasi = durasi;
    }

    public String getDurasi() {
        return durasi;
    }

}

Buat Class : ResponseMovie

package com.meetap.tontonan.model.resApi;

import java.util.List;

import com.google.gson.annotations.SerializedName;

public class ResponseMovie {

    @SerializedName("data")
    private List<DataItem> data;

    @SerializedName("message")
    private String message;

    @SerializedName("status")
    private boolean status;

    public void setData(List<DataItem> data) {
        this.data = data;
    }

    public List<DataItem> getData() {
        return data;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public String getMessage() {
        return message;
    }

    public void setStatus(boolean status) {
        this.status = status;
    }

    public boolean isStatus() {
        return status;
    }
}

Class : ResponseMovie

Buat Interface : ApiInterface 

Klik Kanan > New > Java Class > Kind : Interface

package com.meetap.tontonan.network;

import com.meetap.tontonan.model.resApi.ResponseMovie;

import retrofit2.Call;
import retrofit2.http.GET;

public interface ApiInterface {

    @GET("rest_api_server/")
    Call<ResponseMovie> getListMovie();
}

Ubah Posisi Folder mvp 

Menjadi

class : MovieListActivity

package com.meetap.tontonan.mvp.movielist;

import android.app.ProgressDialog;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.Html;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import com.meetap.tontonan.R;
import com.meetap.tontonan.adapter.MovieAdapter;
import com.meetap.tontonan.model.resApi.DataItem;

import java.util.List;

public class MovieListActivity extends AppCompatActivity implements MovieListContract.View/*,
        LoaderManager.LoaderCallbacks<List<Movie>> */ {

    private RecyclerView rv;
    private Button button ;
    private EditText editText;
 //   private MovieAdapter adapter;
//    private List<Movie> allList;

    private ProgressDialog progressDialog;
    private final static String TAG = MovieListActivity.class.getSimpleName();

    private final MovieListPresenter movieListPresenter = new MovieListPresenter(this);

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_movie_list);
        setTitle(Html.fromHtml("<font color='#000'>List Movie </font>"));
//        allList = new ArrayList<>();

        rv = findViewById(R.id.rvMovieList);
        button = findViewById(R.id.btnSearchMovie);
        editText = findViewById(R.id.edtSearchMovie);


        movieListPresenter.getListAdapter();

        setSearchMovie();

//        getSupportLoaderManager().initLoader(0, null, this);

    }

    private void setSearchMovie() {
        //Melakukan pencarian ketika button di klik
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String text = editText.getText().toString().toLowerCase();
                movieListPresenter.searchMovie(text);
            }
        });
    }

    @Override
    public void showProgress() {
        progressDialog = new ProgressDialog(this);
        progressDialog.setMessage("Loading..");
        progressDialog.setCancelable(false);
        progressDialog.show();
    }

    @Override
    public void hideProgress() {
        progressDialog.dismiss();
    }

    @Override
    public void setUpAdapter(List<DataItem> datalist) {
        rv.setLayoutManager(new LinearLayoutManager(this));
        rv.setAdapter(new MovieAdapter(this, datalist));
    }

    @Override
    public void showErrorMessage(String msg) {
        Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
    }


    //TODO method ini tidak saya gunakan karena datanya belum bisa get dari API
    //TODO sebagai gantinya saya menggunakan edit text dan button untuk melakukan pencarian
    

    //TODO dan untuk asyntasknya juga saya tidak gunakan karena mennggunakan retrofit saja sdh cukup
    /*
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        MenuInflater inflater = getMenuInflater();

        inflater.inflate(R.menu.searchmenu, menu);

        MenuItem searchItem = menu.findItem(R.id.searchM);

        SearchView searchView = (SearchView) MenuItemCompat.getActionView(menu.findItem(R.id.searchM));
        searchView.setQueryHint(getResources().getString(R.string.search_movie));

        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {

            @Override
            public boolean onQueryTextSubmit(String query) {

                Toast.makeText(getApplicationContext(), " " + query, Toast.LENGTH_SHORT).show();

                return false;
            }

            @Override
            public boolean onQueryTextChange(String nextText) {
                Toast.makeText(getApplicationContext(), " " + nextText, Toast.LENGTH_SHORT).show();
                nextText = nextText.toLowerCase();
                ArrayList<Movie> newList = new ArrayList<>();
                for (Movie channel: allList){
                    String channelName = channel.getTittle().toLowerCase();
                    if (channelName.contains(nextText)){
                        newList.add(channel);
                    }
                }
                adapter.setFilter(newList);
                return true;

            }
        });
        searchItem.setActionView(searchView);
        return true;
    }

    public boolean onOptionsItemSelected(MenuItem item) {
        if(item.getItemId() == R.id.action_change_settings){
            Intent intent = new Intent(Settings.ACTION_LOCALE_SETTINGS);
            startActivity(intent);
        }
                return super.onOptionsItemSelected(item);
    }

    */



   /* @NonNull
    @Override
    public Loader<List<Movie>> onCreateLoader(int i, @Nullable Bundle bundle) {
        MyAsyntaskLoader asyncTaskLoader = new MyAsyntaskLoader(this, allList);

        asyncTaskLoader.forceLoad();

        Log.i(TAG, "onCreateLoader");

        return asyncTaskLoader;
    }

    @Override
    public void onLoadFinished(@NonNull Loader<List<Movie>> loader, List<Movie> movies) {
       // adapter.notifyDataSetChanged();

        adapter.setListMovie(movies);
       // loadingBar.setVisibility(View.GONE);

        //listView.setVisibility(View.VISIBLE);

        Log.i(TAG, "onLoadFinish");
    }

    @Override
    public void onLoaderReset(@NonNull Loader<List<Movie>> loader) {
        rv.setAdapter(null);

        Log.i(TAG, "onLoaderReset");
    }

    @Override
    public void setUpAdapter(List<Movie> datalist) {
        adapter = new MovieAdapter(this, allList);

        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
        rv.setLayoutManager(linearLayoutManager);
        rv.setItemAnimator(new DefaultItemAnimator());

        rv.setAdapter(adapter);
    }
    */
}

class : MovieListPresenter

package com.meetap.tontonan.mvp.movielist;

import com.meetap.tontonan.model.resApi.DataItem;
import com.meetap.tontonan.model.resApi.ResponseMovie;
import com.meetap.tontonan.network.ApiClient;
import com.meetap.tontonan.network.ApiInterface;

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

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

public class MovieListPresenter implements MovieListContract.Presenter {

    private final MovieListContract.View view;
    private ApiInterface apiInterface = ApiClient.getClient().create(ApiInterface.class);

    public MovieListPresenter(MovieListContract.View view) {
        this.view = view;
    }

    @Override
    public void getListAdapter() {
        //Menampilkan loading ketika get data berlangsung
        view.showProgress();

        //merequest object call untuk menseting endpoint dan parameter yang di butuhkan
        Call<ResponseMovie> call = apiInterface.getListMovie();

        //Menjalankan request api
        call.enqueue(new Callback<ResponseMovie>() {
            @Override
            public void onResponse(Call<ResponseMovie> call, Response<ResponseMovie> response) {
                //Menutup loading
                view.hideProgress();

                if (response.body() != null) {
                    ResponseMovie responseMovie = response.body();

                    //Cek data list

                    if (responseMovie.getData() != null) {
                        //mengirimkan data ke view
                        view.setUpAdapter(responseMovie.getData());
                    }
                }
            }

            @Override
            public void onFailure(Call<ResponseMovie> call, Throwable t) {
                //Menutup loading ketika kondisi gagal
                view.hideProgress();

                //Menampilkan pesan gagal
                view.showErrorMessage(t.getMessage());
            }
        });
    }

    @Override
    public void searchMovie(final String searchText) {
        if (!searchText.isEmpty()){
            //Menampilkan Loading Ketika Search berlangsung
            view.showProgress();

            //merequest object call untuk menseting endpoint dan parameter yang di butuhkan
            Call<ResponseMovie>call = apiInterface.getListMovie();

            //Menjalankan request api
            call.enqueue(new Callback<ResponseMovie>() {
                @Override
                public void onResponse(Call<ResponseMovie> call, Response<ResponseMovie> response) {
                    //Menutup Loading ketika data tampil
                    view.hideProgress();

                    if (response.body() != null){
                        List<DataItem>dataItemList = response.body().getData();
                        List<DataItem>mDataItemList = new ArrayList<>();

                        for (DataItem data : dataItemList){
                            String title = data.getTitle().toLowerCase();
                            if (title.contains(searchText)){
                                mDataItemList.add(data);
                            }
                        }

                        view.setUpAdapter(mDataItemList);
                    }else {
                        view.showErrorMessage("Tidak Menemukan yang anda cari");
                    }

                }

                @Override
                public void onFailure(Call<ResponseMovie> call, Throwable t) {
                    view.hideProgress();
                    view.showErrorMessage(t.getMessage());
                }
            });

        }else {
            getListAdapter();
        }
    }
}

Interface : MovieListContract

package com.meetap.tontonan.mvp.movielist;

import android.widget.MediaController;
import android.widget.TextView;
import android.widget.VideoView;

import com.meetap.tontonan.model.Movie;
import com.meetap.tontonan.model.resApi.DataItem;

import java.util.List;

public interface MovieListContract {

    interface View {
        void showProgress();

        void hideProgress();

        void setUpAdapter(List<DataItem> datalist);

        void showErrorMessage(String msg);
    }

    interface Presenter {
        void getListAdapter();
        void searchMovie(String searchText);
    }
}

class : DetailMovieActivity

package com.meetap.tontonan.mvp.detailMovie;

import android.app.ProgressDialog;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.Html;
import android.widget.MediaController;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.VideoView;

import com.meetap.tontonan.R;
import com.meetap.tontonan.model.resApi.DataItem;

public class DetailMovieActivity extends AppCompatActivity implements DetailMovieContract.View {

    private DetailMoviePresenter detailMoviePresenter = new DetailMoviePresenter(this);
    private ProgressDialog progressDialog;
    private TextView title, desc;
    private VideoView videoView;
    private MediaController mediaController;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_detail_movie);
        setTitle(Html.fromHtml("<font color='#000'>Detail Movie </font>"));

        Bundle bundle = getIntent().getExtras();
        detailMoviePresenter.getDetail(bundle);

    }

    @Override
    public void showProgress() {
        progressDialog = new ProgressDialog(this);
        progressDialog.setMessage("Loading..");
        progressDialog.setCancelable(false);
        progressDialog.show();

    }

    @Override
    public void hideProgress() {
        progressDialog.dismiss();
    }

    @Override
    public void showDataSingle(DataItem dataItem) {
        title = findViewById(R.id.judul);
        desc = findViewById(R.id.desc);
        videoView = findViewById(R.id.DetailVideo);

        Uri uri = Uri.parse(dataItem.getVideo());

        title.setText(dataItem.getTitle());
        desc.setText(dataItem.getTitle());

        mediaController = new MediaController(this);
        mediaController.setAnchorView(videoView);
        videoView.setMediaController(mediaController);
        videoView.setVideoURI(uri);
        videoView.seekTo(1);
    }

    @Override
    public void ShowFailureMessage(String msg) {
        Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
    }

   /* @Override
    public void detailMovie(TextView title, TextView desc) {
        title = findViewById(R.id.judul);
        desc = findViewById(R.id.desc);

        desc.setText(getIntent().getStringExtra("desc"));
        title.setText(getIntent().getStringExtra("judul"));

    }

    @Override
    public void controller(VideoView videoView, MediaController mediaController) {

        videoView = findViewById(R.id.DetailVideo);

        Uri uri = Uri.parse(getIntent().getStringExtra("Movies"));
        //viewHolder.txtTitle.setText(menu.getTittle());

        mediaController = new MediaController(this);
        mediaController.setAnchorView(videoView);
        videoView.setMediaController(mediaController);
        videoView.setVideoURI(uri);
        videoView.seekTo(1);
    }*/
}

class : DetailMoviePresenter

package com.meetap.tontonan.mvp.detailMovie;

import android.os.Bundle;

import com.meetap.tontonan.model.resApi.DataItem;
import com.meetap.tontonan.model.resApi.ResponseMovie;
import com.meetap.tontonan.network.ApiClient;
import com.meetap.tontonan.network.ApiInterface;

import java.util.List;

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

public class DetailMoviePresenter implements DetailMovieContract.Presenter {

    private final DetailMovieContract.View view;
    private ApiInterface apiInterface = ApiClient.getClient().create(ApiInterface.class);


    private String id;

    public DetailMoviePresenter(DetailMovieContract.View view) {
        this.view = view;
    }

    @Override
    public void getDetail(Bundle bundle) {
        if (bundle != null) {
            id = bundle.getString("id");
        }

        //menampilkan loading ketika get data
        view.showProgress();

        //Menampilkan data dari api
        Call<ResponseMovie> call = apiInterface.getListMovie();
        call.enqueue(new Callback<ResponseMovie>() {
            @Override
            public void onResponse(Call<ResponseMovie> call, Response<ResponseMovie> response) {
                //menutup loading
                view.hideProgress();

                if (response.body() != null) {
                    List<DataItem> dataItemList = response.body().getData();

                    DataItem dataItem = dataItemList.get(0);
                    view.showDataSingle(dataItem);
                }
            }

            @Override
            public void onFailure(Call<ResponseMovie> call, Throwable t) {
                view.hideProgress();
                view.ShowFailureMessage(t.getMessage());
            }
        });
    }


    /*@Override
    public void setDetail() {
        view.detailMovie(title,detail);
        view.controller(videoView,mediaController);
    }*/
}

Interface : DetailMovieContract

package com.meetap.tontonan.mvp.detailMovie;

import android.os.Bundle;
import android.widget.MediaController;
import android.widget.TextView;
import android.widget.VideoView;

import com.meetap.tontonan.model.resApi.DataItem;

public interface DetailMovieContract {

    interface View {
        void showProgress();

        void hideProgress();

        void showDataSingle(DataItem dataItem);

        void ShowFailureMessage(String msg);

    }

    interface Presenter {
        void getDetail(Bundle bundle);
    }

}

update : adapter/MovieAdapter

package com.meetap.tontonan.adapter;

import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.VideoView;

import com.meetap.tontonan.R;
import com.meetap.tontonan.view.DetailMovieActivity;
import com.meetap.tontonan.model.Movie;

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

/**
 * Nama : user
 * Date Created : 06/02/2019
 * Name Project : tontonan
 */
public class MovieAdapter extends RecyclerView.Adapter<MovieAdapter.ViewHolder> {
    private Context context;
    private List<Movie> list;

    public MovieAdapter(Context context,List<Movie> movieList) {
        this.context = context;
        this.list = movieList;
    }
    public void setListMovie(List<Movie> listMovie){
        list = listMovie;
        notifyDataSetChanged();

    }
    @NonNull
    @Override
    public MovieAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_movie, viewGroup, false);
        final MovieAdapter.ViewHolder holder = new MovieAdapter.ViewHolder(v);

        return holder;
    }

    @Override
    public void onBindViewHolder(@NonNull final MovieAdapter.ViewHolder viewHolder, final int i) {
        final Movie movie = list.get(viewHolder.getAdapterPosition());

        String path1 = movie.getVideo();

        Uri uri = Uri.parse(path1);
        viewHolder.txtTitle.setText(movie.getTittle());

        //nanti ini buat detail
         //MediaController mediaController = new MediaController(context);
         //mediaController.setAnchorView(viewHolder.videoView);
         //viewHolder.videoView.setMediaController(mediaController);
        viewHolder.videoView.setVideoURI(uri);
        viewHolder.videoView.seekTo(1);
        viewHolder.relativeLayout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(context, DetailMovieActivity.class);
                intent.putExtra("Movies", movie.getVideo());
                intent.putExtra("judul", movie.getTittle());
                intent.putExtra("desc", movie.getDeskripsi());
                context.startActivity(intent);
            }
        });
    }

    @Override
    public int getItemCount() {
        if(list==null)
            return 0;
        return list.size();
    }

    public class ViewHolder extends RecyclerView.ViewHolder {
        TextView txtTitle;
        VideoView videoView;

        RelativeLayout relativeLayout;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);

            txtTitle = itemView.findViewById(R.id.tvName);
            videoView = itemView.findViewById(R.id.videoview);
            relativeLayout = itemView.findViewById(R.id.header);
        }
    }

    public void setFilter(List<Movie> newList){
        list = new ArrayList<>();
        list.addAll(newList);
        notifyDataSetChanged();
    }
}
package com.meetap.tontonan.adapter;

import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.VideoView;

import com.meetap.tontonan.R;
import com.meetap.tontonan.model.resApi.DataItem;
import com.meetap.tontonan.mvp.detailMovie.DetailMovieActivity;

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

/**
 * Nama : user
 * Date Created : 06/02/2019
 * Name Project : tontonan
 */
public class MovieAdapter extends RecyclerView.Adapter<MovieAdapter.ViewHolder> {
    private Context context;
    private List<DataItem> list;

    //TODO model (Movie) tidak perlu di gunakan lagi karena sudah mengambil data dari API
    //private List<Movie> list;

    /*public MovieAdapter(Context context,List<Movie> movieList) {

        this.context = context;
        this.list = movieList;
    }*/

    public MovieAdapter(Context context, List<DataItem> list) {
        this.context = context;
        this.list = list;
    }

    /*
    public void setListMovie(List<Movie> listMovie){
        list = listMovie;
        notifyDataSetChanged();

    }*/

    public void setListMovie(List<DataItem> listMovie) {
        list = listMovie;
        notifyDataSetChanged();

    }

    @NonNull
    @Override
    public MovieAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_movie, viewGroup, false);
        final MovieAdapter.ViewHolder holder = new MovieAdapter.ViewHolder(v);

        return holder;
    }

    @Override
    public void onBindViewHolder(@NonNull final MovieAdapter.ViewHolder viewHolder, final int i) {
        //final /*Movie*/ DataItem movie = list.get(viewHolder.getAdapterPosition());

        final DataItem movie = list.get(i);

        String path1 = movie.getVideo();

        Uri uri = Uri.parse(path1);
        viewHolder.txtTitle.setText(list.get(i).getTitle());

        //nanti ini buat detail
        //MediaController mediaController = new MediaController(context);
        //mediaController.setAnchorView(viewHolder.videoView);
        //viewHolder.videoView.setMediaController(mediaController);


        viewHolder.videoView.setVideoURI(uri);
        viewHolder.videoView.seekTo(1);

        // TODO sebaiknya |viewHolder.relativeLayout| di ganti menjadi |viewHolder.itemView|
        viewHolder.relativeLayout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
               /* Intent intent = new Intent(context, DetailMovieActivity.class);
                intent.putExtra("Movies", movie.getVideo());
                intent.putExtra("judul", movie.getTitle());
                intent.putExtra("desc", movie.getTitle());
                context.startActivity(intent);*/

                //Perpindahan data menggunakan Bundle karena ketika pindah ke detail bisa get data
                Bundle bundle = new Bundle();
                bundle.putString("id", movie.getId());

                //Berpindah halaman dengan membawa data
                context.startActivity(new Intent(context, DetailMovieActivity.class).putExtras(bundle));
            }
        });
    }

    @Override
    public int getItemCount() {
        if (list == null)
            return 0;
        return list.size();
    }

    class ViewHolder extends RecyclerView.ViewHolder {
        TextView txtTitle;
        VideoView videoView;

        RelativeLayout relativeLayout;

        ViewHolder(@NonNull View itemView) {
            super(itemView);

            txtTitle = itemView.findViewById(R.id.tvName);
            videoView = itemView.findViewById(R.id.videoview);
            relativeLayout = itemView.findViewById(R.id.header);
        }
    }

    /*public void setFilter(List<Movie> newList){
        list = new ArrayList<>();
        list.addAll(newList);
        notifyDataSetChanged();
    }*/

    public void setFilter(List<DataItem> newList) {
        list = new ArrayList<>();
        list.addAll(newList);
        notifyDataSetChanged();
    }


}

Before

After

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:padding="16dp">

        <!-- Top Sliding Banners -->

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="200dp">


            <android.support.v4.view.ViewPager
                android:id="@+id/pager"
                android:layout_width="wrap_content"
                android:layout_height="fill_parent"
                android:layout_alignParentTop="true" />

            <com.viewpagerindicator.CirclePageIndicator
                android:id="@+id/indicator"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_alignParentBottom="true"
                android:layout_centerHorizontal="true"
                android:gravity="bottom"
                android:padding="10dip"
                app:centered="true"
                app:fillColor="@color/lime_dark"
                app:pageColor="@color/white"
                app:snap="false" />

        </RelativeLayout>

        <HorizontalScrollView
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <android.support.v7.widget.CardView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                app:cardBackgroundColor="@color/white"
                app:cardCornerRadius="8dp"
                app:cardUseCompatPadding="true"
                app:cardElevation="2dp"
                android:layout_marginTop="8dp">
            <RelativeLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="16dp">

                <LinearLayout
                    android:id="@+id/logo1"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:gravity="center"
                    android:orientation="vertical"
                    android:padding="8dp">

                    <ImageView
                        android:layout_width="80dp"
                        android:layout_height="80dp"
                        android:src="@drawable/action_icon" />

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_marginTop="8dp"
                        android:text="Action" />
                </LinearLayout>


                <LinearLayout
                    android:id="@+id/logo2"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="18dp"
                    android:layout_toRightOf="@+id/logo1"
                    android:gravity="center"
                    android:orientation="vertical"
                    android:padding="8dp">

                    <ImageView
                        android:layout_width="80dp"
                        android:layout_height="80dp"
                        android:src="@drawable/comedy_icon" />

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_marginTop="8dp"
                        android:text="Action" />
                </LinearLayout>


                <LinearLayout
                    android:id="@+id/logo3"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="18dp"
                    android:layout_toRightOf="@+id/logo2"
                    android:gravity="center"
                    android:orientation="vertical"
                    android:padding="8dp">

                    <ImageView
                        android:layout_width="80dp"
                        android:layout_height="80dp"
                        android:src="@drawable/ic_horror" />

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_marginTop="8dp"
                        android:text="Action" />
                </LinearLayout>

                <LinearLayout
                    android:id="@+id/logo4"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="18dp"
                    android:layout_toRightOf="@+id/logo3"
                    android:gravity="center"
                    android:orientation="vertical"
                    android:padding="8dp">

                    <ImageView
                        android:layout_width="80dp"
                        android:layout_height="80dp"
                        android:src="@drawable/ic_favorite_black_24dp" />

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_marginTop="8dp"
                        android:text="Action" />
                </LinearLayout>
            </RelativeLayout>
            </android.support.v7.widget.CardView>
        </HorizontalScrollView>

        <RelativeLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">

            <LinearLayout
                android:id="@+id/bkiri"
                android:layout_width="130dp"
                android:layout_height="1dp"
                android:background="@color/black"
                android:gravity="center"
                android:layout_marginTop="8dp"
                android:orientation="vertical">
            </LinearLayout>
            <TextView
                android:id="@+id/popular"
                android:layout_marginRight="8dp"
                android:layout_toRightOf="@+id/bkiri"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="8dp"
                android:text="Popular"/>
            <LinearLayout
                android:layout_toRightOf="@+id/popular"
                android:layout_width="130dp"
                android:layout_height="1dp"
                android:background="@color/black"
                android:gravity="center"
                android:layout_marginTop="8dp"
                android:orientation="vertical">
            </LinearLayout>
        </RelativeLayout>

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

        </android.support.v7.widget.RecyclerView>
    </LinearLayout>
</ScrollView>

activity_main.xml

item_movie.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingTop="10dp"
    card_view:cardBackgroundColor="@color/white"
    card_view:cardCornerRadius="8dp"
    card_view:cardUseCompatPadding="true">

    <RelativeLayout
        android:id="@+id/header"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">


        <VideoView
            android:id="@+id/videoview"
            android:layout_width="match_parent"
            android:layout_height="180dp"
            android:layout_alignParentLeft="true"
            android:layout_alignParentRight="true"
            android:layout_alignParentTop="true" />

        <TextView
            android:id="@+id/tvName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/videoview"
            android:layout_marginStart="4dp"
            android:textColor="@color/teal_800"
            android:textSize="24sp"
            tools:text="Ini judul movie" />

    </RelativeLayout>
</android.support.v7.widget.CardView>

activity_movie_list.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:padding="8dp"
    tools:context=".mvp.movielist.MovieListActivity">

    <android.support.v7.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:padding="10dp">

        <android.support.constraint.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="10dp">

            <EditText
                android:id="@+id/edtSearchMovie"
                android:layout_width="276dp"
                android:layout_height="wrap_content"
                android:layout_alignParentStart="true"
                android:layout_marginBottom="8dp"
                android:layout_marginEnd="4dp"
                android:layout_marginTop="8dp"
                android:hint="Search Movie"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toStartOf="@+id/btnSearchMovie"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent" />

            <Button
                android:id="@+id/btnSearchMovie"
                style="@style/Widget.AppCompat.Button.Colored"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentEnd="true"
                android:layout_marginBottom="8dp"
                android:layout_marginEnd="6dp"
                android:layout_marginStart="1dp"
                android:text="Search"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toEndOf="@+id/edtSearchMovie"
                app:layout_constraintTop_toTopOf="parent" />

        </android.support.constraint.ConstraintLayout>
    </android.support.v7.widget.CardView>


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

</LinearLayout>

activity_detail_movie.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"
    android:orientation="vertical"
    tools:context=".mvp.detailMovie.DetailMovieActivity">


    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="4dp">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/video">
        <VideoView
            android:layout_width="match_parent"
            android:layout_height="200dp"
            android:id="@+id/DetailVideo"
            android:layout_alignParentLeft="true"
            android:layout_alignParentRight="true"
            android:layout_alignParentTop="true"/>
        </LinearLayout>

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@+id/video"
            android:id="@+id/header">
            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/love"
                android:orientation="vertical">
                <ImageView
                    android:layout_width="70dp"
                    android:layout_height="70dp"
                    android:src="@drawable/ic_favorite_border"/>
                <TextView

                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="@string/love"
                    android:layout_gravity="center"
                    android:textSize="20sp"/>
            </LinearLayout>

            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="33dp"
                android:id="@+id/comment"
                android:layout_toRightOf="@id/love"
                android:orientation="vertical">
                <ImageView
                    android:layout_width="70dp"
                    android:layout_height="70dp"
                    android:layout_gravity="center"
                    android:src="@drawable/ic_chat_bubble"/>
                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="@string/comment"
                    android:layout_gravity="center"
                    android:textSize="20sp"/>
            </LinearLayout>

            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="33dp"
                android:id="@+id/bookmark"
                android:layout_toRightOf="@id/comment"
                android:orientation="vertical">
                <ImageView
                    android:layout_width="70dp"
                    android:layout_height="70dp"
                    android:layout_gravity="center"
                    android:src="@drawable/ic_bookmark_border"/>
                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="@string/bookmark"
                    android:layout_gravity="center"
                    android:textSize="20sp"/>
            </LinearLayout>
        </RelativeLayout>
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/header"
            android:layout_marginTop="16dp"
            android:id="@+id/profile">

            <de.hdodenhof.circleimageview.CircleImageView
                android:layout_width="70dp"
                android:layout_height="70dp"
                android:src="@mipmap/ic_launcher_round"/>
            <TextView
                android:id="@+id/judul"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Belajar Android"
                android:textSize="26sp"
                android:textStyle="bold"
                android:layout_marginLeft="8dp"
                android:layout_gravity="center"/>

        </LinearLayout>
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Published : "
            android:layout_below="@id/profile"
            android:id="@+id/publish"/>
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Feb 05, 2019"
            android:layout_toRightOf="@id/publish"
            android:layout_below="@id/profile"/>

        <TextView
            android:id="@+id/desc"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Deskripsi vidio"
            android:layout_below="@id/publish"
            android:layout_marginTop="16dp"/>



    </RelativeLayout>




</LinearLayout>

item_view_pager.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="1dip" >

    <ImageView
        android:id="@+id/image"
        android:layout_width="match_parent"
        android:layout_height="250dp"
        android:src="@mipmap/ic_launcher"
        android:scaleType="fitXY" />
</FrameLayout>
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <item
    android:id="@+id/action_change_settings"
    android:title="Change Language Settings"
    app:showAsAction="never"/>

    <item android:id="@+id/searchM"
        android:title="search"
        android:icon="@drawable/ic_search"
        app:showAsAction="collapseActionView|ifRoom"
        app:actionViewClass="android.widget.SearchView" />
</menu>

search_menu.xml

Struktur File Java

Struktur File res

Tampilan List Movie

Tampilan Pencarian

Tampilan Detail Movie

Download 

REST API Client dengan Retrofit pada Android Studio

By Maulana Ilham

REST API Client dengan Retrofit pada Android Studio

REST API Client dengan Retrofit pada Android Studio

  • 1,265