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