From 746ccc7c109f837330dd8d9f5ce9ed38a37e84d6 Mon Sep 17 00:00:00 2001 From: Hein Htet Date: Sat, 9 Dec 2017 20:39:15 +0630 Subject: [PATCH 1/9] add GridLayoutManager_SpanGridSize --- .idea/modules.xml | 6 +- .../com/suleiman/pagination/MainActivity.java | 71 ++++++++++++++++--- .../pagination/PaginationAdapter.java | 38 ++++++---- .../utils/PaginationAdapterCallback.java | 3 - .../utils/PaginationScrollListener.java | 5 -- 5 files changed, 90 insertions(+), 33 deletions(-) diff --git a/.idea/modules.xml b/.idea/modules.xml index 4af7707..683670b 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -2,9 +2,11 @@ - - + + + + \ No newline at end of file diff --git a/app/src/main/java/com/suleiman/pagination/MainActivity.java b/app/src/main/java/com/suleiman/pagination/MainActivity.java index 656e8ad..916b4e8 100644 --- a/app/src/main/java/com/suleiman/pagination/MainActivity.java +++ b/app/src/main/java/com/suleiman/pagination/MainActivity.java @@ -5,6 +5,7 @@ import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.DefaultItemAnimator; +import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.util.Log; @@ -34,6 +35,7 @@ public class MainActivity extends AppCompatActivity implements PaginationAdapter PaginationAdapter adapter; LinearLayoutManager linearLayoutManager; + GridLayoutManager gridLayoutManager; RecyclerView rv; ProgressBar progressBar; @@ -66,18 +68,35 @@ protected void onCreate(Bundle savedInstanceState) { adapter = new PaginationAdapter(this); linearLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false); - rv.setLayoutManager(linearLayoutManager); - rv.setItemAnimator(new DefaultItemAnimator()); + gridLayoutManager = new GridLayoutManager(this, 2 + ); + gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() { + @Override + public int getSpanSize(int position) { + switch (adapter.getItemViewType(position)) { + case PaginationAdapter.HERO: + return 2; // spacing 2 row in 1 items + case PaginationAdapter.ITEM: + return 1; // spacing 1 row in 1 items + case PaginationAdapter.LOADING: + return 2;// spacing 2 row in 1 items + default: + return -1; + } + } + }); + rv.setLayoutManager(gridLayoutManager); + rv.setItemAnimator(new DefaultItemAnimator()); rv.setAdapter(adapter); - rv.addOnScrollListener(new PaginationScrollListener(linearLayoutManager) { + + rv.addOnScrollListener(new PaginationScrollListener(gridLayoutManager) { @Override protected void loadMoreItems() { isLoading = true; currentPage += 1; - - loadNextPage(); + loadApi("next"); } @Override @@ -99,12 +118,12 @@ public boolean isLoading() { //init service and load data movieService = MovieApi.getClient().create(MovieService.class); - loadFirstPage(); + loadApi("first"); btnRetry.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { - loadFirstPage(); + loadApi("first"); } }); @@ -149,7 +168,10 @@ private List fetchResults(Response response) { return topRatedMovies.getResults(); } - private void loadNextPage() { + private void loadNextPage(String type) { + if (type.equals("first")) { + hideErrorView(); + } Log.d(TAG, "loadNextPage: " + currentPage); callTopRatedMoviesApi().enqueue(new Callback() { @@ -173,6 +195,37 @@ public void onFailure(Call call, Throwable t) { }); } + /*adding type and call api method write once*/ + private void loadApi(final String type) { + callTopRatedMoviesApi().enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + if (type.equals("first")) { + Log.d(TAG, "loadFirstPage: " + currentPage); + hideErrorView(); + List results = fetchResults(response); + progressBar.setVisibility(View.GONE); + adapter.addAll(results); + } else { + Log.d(TAG, "loadNextPage: " + currentPage); + adapter.removeLoadingFooter(); + isLoading = false; + List results = fetchResults(response); + adapter.addAll(results); + } + + if (currentPage != TOTAL_PAGES) adapter.addLoadingFooter(); + else isLastPage = true; + } + + @Override + public void onFailure(Call call, Throwable t) { + t.printStackTrace(); + adapter.showRetry(true, fetchErrorMessage(t)); + } + }); + } + /** * Performs a Retrofit call to the top rated movies API. @@ -191,7 +244,7 @@ private Call callTopRatedMoviesApi() { @Override public void retryPageLoad() { - loadNextPage(); + loadApi("more"); } diff --git a/app/src/main/java/com/suleiman/pagination/PaginationAdapter.java b/app/src/main/java/com/suleiman/pagination/PaginationAdapter.java index 09aad46..e24d050 100644 --- a/app/src/main/java/com/suleiman/pagination/PaginationAdapter.java +++ b/app/src/main/java/com/suleiman/pagination/PaginationAdapter.java @@ -25,16 +25,13 @@ import java.util.ArrayList; import java.util.List; -/** - * Created by Suleiman on 19/10/16. - */ public class PaginationAdapter extends RecyclerView.Adapter { // View Types - private static final int ITEM = 0; - private static final int LOADING = 1; - private static final int HERO = 2; + public static final int ITEM = 0; + public static final int LOADING = 1; + public static final int HERO = 2; private static final String BASE_URL_IMG = "https://image.tmdb.org/t/p/w150"; @@ -90,20 +87,22 @@ public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { switch (getItemViewType(position)) { + case HERO: final HeroVH heroVh = (HeroVH) holder; - heroVh.mMovieTitle.setText(result.getTitle()); - heroVh.mYear.setText(formatYearLabel(result)); + if (result.getTitle() != null) { + heroVh.mYear.setText(formatYearLabel(result)); + } else { + heroVh.mYear.setText("null"); + } heroVh.mMovieDesc.setText(result.getOverview()); loadImage(result.getBackdropPath()) .into(heroVh.mPosterImg); break; - case ITEM: final MovieVH movieVH = (MovieVH) holder; - movieVH.mMovieTitle.setText(result.getTitle()); movieVH.mYear.setText(formatYearLabel(result)); movieVH.mMovieDesc.setText(result.getOverview()); @@ -155,11 +154,17 @@ public int getItemCount() { @Override public int getItemViewType(int position) { - if (position == 0) { + if (position % 3 == 0) { return HERO; } else { return (position == movieResults.size() - 1 && isLoadingAdded) ? LOADING : ITEM; + } +// if (position == 0) { +// return HERO; +// } else { +// return (position == movieResults.size() - 1 && isLoadingAdded) ? LOADING : ITEM; +// } } /* @@ -172,9 +177,14 @@ public int getItemViewType(int position) { * @return [releasedate] | [2letterlangcode] */ private String formatYearLabel(Result result) { - return result.getReleaseDate().substring(0, 4) // we want the year only - + " | " - + result.getOriginalLanguage().toUpperCase(); + if (result != null) { + return result.getReleaseDate().substring(0, 4) // we want the year only + + " | " + + result.getOriginalLanguage().toUpperCase(); + + } else { + return ""; + } } /** diff --git a/app/src/main/java/com/suleiman/pagination/utils/PaginationAdapterCallback.java b/app/src/main/java/com/suleiman/pagination/utils/PaginationAdapterCallback.java index a3d987d..03b7dfc 100644 --- a/app/src/main/java/com/suleiman/pagination/utils/PaginationAdapterCallback.java +++ b/app/src/main/java/com/suleiman/pagination/utils/PaginationAdapterCallback.java @@ -1,8 +1,5 @@ package com.suleiman.pagination.utils; -/** - * Created by Suleiman on 16/11/16. - */ public interface PaginationAdapterCallback { diff --git a/app/src/main/java/com/suleiman/pagination/utils/PaginationScrollListener.java b/app/src/main/java/com/suleiman/pagination/utils/PaginationScrollListener.java index 7d59d44..f054e2e 100755 --- a/app/src/main/java/com/suleiman/pagination/utils/PaginationScrollListener.java +++ b/app/src/main/java/com/suleiman/pagination/utils/PaginationScrollListener.java @@ -3,11 +3,6 @@ import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; -/** - * Pagination - * Created by Suleiman19 on 10/15/16. - * Copyright (c) 2016. Suleiman Ali Shakir. All rights reserved. - */ public abstract class PaginationScrollListener extends RecyclerView.OnScrollListener { LinearLayoutManager layoutManager; From 0b93327e7129ac99726367b6de924afd0e2f749d Mon Sep 17 00:00:00 2001 From: Hein Htet Date: Sat, 9 Dec 2017 21:03:17 +0630 Subject: [PATCH 2/9] add swife_refershLayout --- .../com/suleiman/pagination/MainActivity.java | 29 ++++++++++++++++++- .../pagination/PaginationAdapter.java | 17 ++++++++++- .../utils/PaginationAdapterCallback.java | 4 +++ app/src/main/res/layout/activity_main.xml | 6 ++++ 4 files changed, 54 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/suleiman/pagination/MainActivity.java b/app/src/main/java/com/suleiman/pagination/MainActivity.java index 916b4e8..324fffb 100644 --- a/app/src/main/java/com/suleiman/pagination/MainActivity.java +++ b/app/src/main/java/com/suleiman/pagination/MainActivity.java @@ -1,8 +1,10 @@ package com.suleiman.pagination; +import android.annotation.SuppressLint; import android.content.Context; import android.net.ConnectivityManager; import android.os.Bundle; +import android.support.v4.widget.SwipeRefreshLayout; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.DefaultItemAnimator; import android.support.v7.widget.GridLayoutManager; @@ -14,6 +16,7 @@ import android.widget.LinearLayout; import android.widget.ProgressBar; import android.widget.TextView; +import android.widget.Toast; import com.suleiman.pagination.api.MovieApi; import com.suleiman.pagination.api.MovieService; @@ -42,6 +45,7 @@ public class MainActivity extends AppCompatActivity implements PaginationAdapter LinearLayout errorLayout; Button btnRetry; TextView txtError; + SwipeRefreshLayout swipeRefreshLayout; private static final int PAGE_START = 1; @@ -54,6 +58,7 @@ public class MainActivity extends AppCompatActivity implements PaginationAdapter private MovieService movieService; + @SuppressLint("ResourceAsColor") @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -64,6 +69,18 @@ protected void onCreate(Bundle savedInstanceState) { errorLayout = (LinearLayout) findViewById(R.id.error_layout); btnRetry = (Button) findViewById(R.id.error_btn_retry); txtError = (TextView) findViewById(R.id.error_txt_cause); + swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_layout); + swipeRefreshLayout.setColorScheme(android.R.color.holo_green_light, + android.R.color.holo_orange_light, + android.R.color.holo_red_light); + swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { + @Override + public void onRefresh() { + adapter.clear(); + currentPage = PAGE_START; + loadApi("first"); + } + }); adapter = new PaginationAdapter(this); @@ -142,7 +159,7 @@ public void onResponse(Call call, Response respo // Got data. Send it to adapter hideErrorView(); - + hideSwifeRefresh(); List results = fetchResults(response); progressBar.setVisibility(View.GONE); adapter.addAll(results); @@ -159,6 +176,10 @@ public void onFailure(Call call, Throwable t) { }); } + private void hideSwifeRefresh() { + swipeRefreshLayout.setRefreshing(false); + } + /** * @param response extracts List<{@link Result>} from response * @return @@ -203,6 +224,7 @@ public void onResponse(Call call, Response respo if (type.equals("first")) { Log.d(TAG, "loadFirstPage: " + currentPage); hideErrorView(); + hideSwifeRefresh(); List results = fetchResults(response); progressBar.setVisibility(View.GONE); adapter.addAll(results); @@ -247,6 +269,11 @@ public void retryPageLoad() { loadApi("more"); } + @Override + public void onItemsClickListener(Result result, int position) { + Toast.makeText(this, "You click " + position + " items " + result.getTitle(), Toast.LENGTH_SHORT).show(); + } + /** * @param throwable required for {@link #fetchErrorMessage(Throwable)} diff --git a/app/src/main/java/com/suleiman/pagination/PaginationAdapter.java b/app/src/main/java/com/suleiman/pagination/PaginationAdapter.java index e24d050..5ea30bb 100644 --- a/app/src/main/java/com/suleiman/pagination/PaginationAdapter.java +++ b/app/src/main/java/com/suleiman/pagination/PaginationAdapter.java @@ -104,7 +104,9 @@ public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { case ITEM: final MovieVH movieVH = (MovieVH) holder; movieVH.mMovieTitle.setText(result.getTitle()); - movieVH.mYear.setText(formatYearLabel(result)); + if (result.getTitle() != null) { + movieVH.mYear.setText(formatYearLabel(result)); + } movieVH.mMovieDesc.setText(result.getOverview()); // load movie thumbnail @@ -297,6 +299,13 @@ public HeroVH(View itemView) { mMovieDesc = (TextView) itemView.findViewById(R.id.movie_desc); mYear = (TextView) itemView.findViewById(R.id.movie_year); mPosterImg = (ImageView) itemView.findViewById(R.id.movie_poster); + + itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + mCallback.onItemsClickListener(movieResults.get(getAdapterPosition()), getAdapterPosition()); + } + }); } } @@ -318,6 +327,12 @@ public MovieVH(View itemView) { mYear = (TextView) itemView.findViewById(R.id.movie_year); mPosterImg = (ImageView) itemView.findViewById(R.id.movie_poster); mProgress = (ProgressBar) itemView.findViewById(R.id.movie_progress); + itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + mCallback.onItemsClickListener(movieResults.get(getAdapterPosition()), getAdapterPosition()); + } + }); } } diff --git a/app/src/main/java/com/suleiman/pagination/utils/PaginationAdapterCallback.java b/app/src/main/java/com/suleiman/pagination/utils/PaginationAdapterCallback.java index 03b7dfc..5c8a30c 100644 --- a/app/src/main/java/com/suleiman/pagination/utils/PaginationAdapterCallback.java +++ b/app/src/main/java/com/suleiman/pagination/utils/PaginationAdapterCallback.java @@ -1,7 +1,11 @@ package com.suleiman.pagination.utils; +import com.suleiman.pagination.models.Result; + public interface PaginationAdapterCallback { void retryPageLoad(); + + void onItemsClickListener(Result result, int position); } diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 94f83bc..5e5d878 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,4 +1,9 @@ + + \ No newline at end of file From 7889c151f68c293c551dbb965b376f719271ff01 Mon Sep 17 00:00:00 2001 From: Hein Htet Date: Sat, 9 Dec 2017 21:13:08 +0630 Subject: [PATCH 3/9] add specific remove row --- .../java/com/suleiman/pagination/MainActivity.java | 8 ++++++++ .../com/suleiman/pagination/PaginationAdapter.java | 14 +++++++++++++- .../utils/PaginationAdapterCallback.java | 2 ++ .../pagination/utils/PaginationScrollListener.java | 5 +++++ 4 files changed, 28 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/suleiman/pagination/MainActivity.java b/app/src/main/java/com/suleiman/pagination/MainActivity.java index 324fffb..6f4c1cc 100644 --- a/app/src/main/java/com/suleiman/pagination/MainActivity.java +++ b/app/src/main/java/com/suleiman/pagination/MainActivity.java @@ -73,6 +73,8 @@ protected void onCreate(Bundle savedInstanceState) { swipeRefreshLayout.setColorScheme(android.R.color.holo_green_light, android.R.color.holo_orange_light, android.R.color.holo_red_light); + + swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { @Override public void onRefresh() { @@ -271,9 +273,15 @@ public void retryPageLoad() { @Override public void onItemsClickListener(Result result, int position) { + adapter.removeAtItemsPosition(position); Toast.makeText(this, "You click " + position + " items " + result.getTitle(), Toast.LENGTH_SHORT).show(); } + @Override + public void emptyLayout() { + Toast.makeText(this, "empty items", Toast.LENGTH_SHORT).show(); + } + /** * @param throwable required for {@link #fetchErrorMessage(Throwable)} diff --git a/app/src/main/java/com/suleiman/pagination/PaginationAdapter.java b/app/src/main/java/com/suleiman/pagination/PaginationAdapter.java index 5ea30bb..727746c 100644 --- a/app/src/main/java/com/suleiman/pagination/PaginationAdapter.java +++ b/app/src/main/java/com/suleiman/pagination/PaginationAdapter.java @@ -151,7 +151,13 @@ public boolean onResourceReady(GlideDrawable resource, String model, Target Date: Sat, 9 Dec 2017 21:30:39 +0630 Subject: [PATCH 4/9] add kotlinUtils&adapter --- app/build.gradle | 5 + .../com/kotlinUtils/PaginatioinAdapter.kt | 355 ++++++++++++++++++ .../kotlinUtils/PaginationScrollListener.kt | 37 ++ .../com/suleiman/pagination/MainActivity.java | 6 +- .../utils/PaginationScrollListener.java | 1 - app/src/main/res/layout/item_hero.xml | 1 + build.gradle | 2 + 7 files changed, 403 insertions(+), 4 deletions(-) create mode 100644 app/src/main/java/com/kotlinUtils/PaginatioinAdapter.kt create mode 100644 app/src/main/java/com/kotlinUtils/PaginationScrollListener.kt diff --git a/app/build.gradle b/app/build.gradle index 6b992cf..fefc89d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,4 +1,5 @@ apply plugin: 'com.android.application' +apply plugin: 'kotlin-android' android { compileSdkVersion 25 @@ -33,4 +34,8 @@ dependencies { compile 'com.squareup.retrofit2:converter-gson:2.1.0' compile 'com.github.bumptech.glide:glide:3.7.0' compile 'com.squareup.okhttp3:logging-interceptor:3.3.1' + compile "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" +} +repositories { + mavenCentral() } diff --git a/app/src/main/java/com/kotlinUtils/PaginatioinAdapter.kt b/app/src/main/java/com/kotlinUtils/PaginatioinAdapter.kt new file mode 100644 index 0000000..4140d13 --- /dev/null +++ b/app/src/main/java/com/kotlinUtils/PaginatioinAdapter.kt @@ -0,0 +1,355 @@ +package com.kotlinUtils + +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.* +import com.bumptech.glide.DrawableRequestBuilder +import com.bumptech.glide.Glide +import com.bumptech.glide.load.engine.DiskCacheStrategy +import com.bumptech.glide.load.resource.drawable.GlideDrawable +import com.bumptech.glide.request.RequestListener +import com.bumptech.glide.request.target.Target +import com.suleiman.pagination.R +import com.suleiman.pagination.models.Result +import com.suleiman.pagination.utils.PaginationAdapterCallback +import java.util.ArrayList + +/** + * Created by heinhtet on 12/9/2017. + */ + + +class PaginationAdapter(private val context: Context) : RecyclerView.Adapter() { + + private var movieResults: MutableList? = null + + private var isLoadingAdded = false + private var retryPageLoad = false + + private val mCallback: PaginationAdapterCallback + + private var errorMsg: String? = null + + var movies: MutableList? + get() = movieResults + set(movieResults) { + this.movieResults = movieResults + } + + val isEmpty: Boolean + get() = itemCount == 0 + + init { + this.mCallback = context as PaginationAdapterCallback + movieResults = ArrayList() + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder? { + var viewHolder: RecyclerView.ViewHolder? = null + val inflater = LayoutInflater.from(parent.context) + + when (viewType) { + ITEM -> { + val viewItem = inflater.inflate(R.layout.item_list, parent, false) + viewHolder = MovieVH(viewItem) + } + LOADING -> { + val viewLoading = inflater.inflate(R.layout.item_progress, parent, false) + viewHolder = LoadingVH(viewLoading) + } + HERO -> { + val viewHero = inflater.inflate(R.layout.item_hero, parent, false) + viewHolder = HeroVH(viewHero) + } + } + return viewHolder + } + + override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { + val result = movieResults!![position] // Movie + + when (getItemViewType(position)) { + + + HERO -> { + val heroVh = holder as HeroVH + heroVh.mMovieTitle.text = result.title + if (result.title != null) { + heroVh.mYear.text = formatYearLabel(result) + } else { + heroVh.mYear.text = "null" + } + heroVh.mMovieDesc.text = result.overview + + loadImage(result.backdropPath) + .into(heroVh.mPosterImg) + } + ITEM -> { + val movieVH = holder as MovieVH + movieVH.mMovieTitle.text = result.title + if (result.title != null) { + movieVH.mYear.text = formatYearLabel(result) + } + movieVH.mMovieDesc.text = result.overview + + // load movie thumbnail + loadImage(result.posterPath) + .listener(object : RequestListener { + override fun onException(e: Exception, model: String, target: Target, isFirstResource: Boolean): Boolean { + // TODO: 08/11/16 handle failure + movieVH.mProgress.visibility = View.GONE + return false + } + + override fun onResourceReady(resource: GlideDrawable, model: String, target: Target, isFromMemoryCache: Boolean, isFirstResource: Boolean): Boolean { + // image ready, hide progress now + movieVH.mProgress.visibility = View.GONE + return false // return false if you want Glide to handle everything else. + } + }) + .into(movieVH.mPosterImg) + } + + LOADING -> { + val loadingVH = holder as LoadingVH + + if (retryPageLoad) { + loadingVH.mErrorLayout.visibility = View.VISIBLE + loadingVH.mProgressBar.visibility = View.GONE + + loadingVH.mErrorTxt.text = if (errorMsg != null) + errorMsg + else + context.getString(R.string.error_msg_unknown) + + } else { + loadingVH.mErrorLayout.visibility = View.GONE + loadingVH.mProgressBar.visibility = View.VISIBLE + } + } + } + } + + override fun getItemCount(): Int { + if (movieResults == null) { + mCallback.emptyLayout() + return 0 + } else { + return movieResults!!.size + } + // return movieResults == null ? 0 : movieResults.size() + } + + override fun getItemViewType(position: Int): Int { + return if (position % 3 == 0) { + HERO + } else { + if (position == movieResults!!.size - 1 && isLoadingAdded) LOADING else ITEM + + } + // if (position == 0) { + // return HERO; + // } else { + // return (position == movieResults.size() - 1 && isLoadingAdded) ? LOADING : ITEM; + // } + } + + /* + Helpers - bind Views + _________________________________________________________________________________________________ + */ + + /** + * @param result + * @return [releasedate] | [2letterlangcode] + */ + private fun formatYearLabel(result: Result?): String { + return if (result != null) { + (result.releaseDate.substring(0, 4) // we want the year only + + + " | " + + result.originalLanguage.toUpperCase()) + + } else { + "" + } + } + + /** + * Using Glide to handle image loading. + * Learn more about Glide here: + * [](http://blog.grafixartist.com/image-gallery-app-android-studio-1-4-glide/) + * + * @param posterPath from [Result.getPosterPath] + * @return Glide builder + */ + private fun loadImage(posterPath: String): DrawableRequestBuilder { + return Glide + .with(context) + .load(BASE_URL_IMG + posterPath) + .diskCacheStrategy(DiskCacheStrategy.ALL) // cache both original & resized image + .centerCrop() + .crossFade() + } + + + /* + Helpers - Pagination + _________________________________________________________________________________________________ + */ + + fun add(r: Result) { + movieResults!!.add(r) + notifyItemInserted(movieResults!!.size - 1) + } + + fun addAll(moveResults: List) { + for (result in moveResults) { + add(result) + } + } + + fun remove(r: Result?) { + val position = movieResults!!.indexOf(r) + if (position > -1) { + movieResults!!.removeAt(position) + notifyItemRemoved(position) + } + } + + fun clear() { + isLoadingAdded = false + while (itemCount > 0) { + remove(getItem(0)) + } + } + + fun removeAtItemsPosition(position: Int) { + movieResults!!.removeAt(position) + notifyItemRemoved(position) + notifyItemRangeChanged(position, movieResults!!.size) + } + + + fun addLoadingFooter() { + isLoadingAdded = true + add(Result()) + } + + fun removeLoadingFooter() { + isLoadingAdded = false + + val position = movieResults!!.size - 1 + val result = getItem(position) + + if (result != null) { + movieResults!!.removeAt(position) + notifyItemRemoved(position) + } + } + + fun getItem(position: Int): Result? { + return movieResults!![position] + } + + /** + * Displays Pagination retry footer view along with appropriate errorMsg + * + * @param show + * @param errorMsg to display if page load fails + */ + fun showRetry(show: Boolean, errorMsg: String?) { + retryPageLoad = show + notifyItemChanged(movieResults!!.size - 1) + + if (errorMsg != null) this.errorMsg = errorMsg + } + + + /* + View Holders + _________________________________________________________________________________________________ + */ + + /** + * Header ViewHolder + */ + protected inner class HeroVH(itemView: View) : RecyclerView.ViewHolder(itemView) { + val mMovieTitle: TextView + val mMovieDesc: TextView + val mYear: TextView // displays "year | language" + val mPosterImg: ImageView + + init { + mMovieTitle = itemView.findViewById(R.id.movie_title) as TextView + mMovieDesc = itemView.findViewById(R.id.movie_desc) as TextView + mYear = itemView.findViewById(R.id.movie_year) as TextView + mPosterImg = itemView.findViewById(R.id.movie_poster) as ImageView + + itemView.setOnClickListener { mCallback.onItemsClickListener(movieResults!![adapterPosition], adapterPosition) } + } + } + + /** + * Main list's content ViewHolder + */ + protected inner class MovieVH(itemView: View) : RecyclerView.ViewHolder(itemView) { + val mMovieTitle: TextView + val mMovieDesc: TextView + val mYear: TextView // displays "year | language" + val mPosterImg: ImageView + val mProgress: ProgressBar + + init { + + mMovieTitle = itemView.findViewById(R.id.movie_title) as TextView + mMovieDesc = itemView.findViewById(R.id.movie_desc) as TextView + mYear = itemView.findViewById(R.id.movie_year) as TextView + mPosterImg = itemView.findViewById(R.id.movie_poster) as ImageView + mProgress = itemView.findViewById(R.id.movie_progress) as ProgressBar + itemView.setOnClickListener { mCallback.onItemsClickListener(movieResults!![adapterPosition], adapterPosition) } + } + } + + + protected inner class LoadingVH(itemView: View) : RecyclerView.ViewHolder(itemView), View.OnClickListener { + val mProgressBar: ProgressBar + val mRetryBtn: ImageButton + val mErrorTxt: TextView + val mErrorLayout: LinearLayout + + init { + + mProgressBar = itemView.findViewById(R.id.loadmore_progress) as ProgressBar + mRetryBtn = itemView.findViewById(R.id.loadmore_retry) as ImageButton + mErrorTxt = itemView.findViewById(R.id.loadmore_errortxt) as TextView + mErrorLayout = itemView.findViewById(R.id.loadmore_errorlayout) as LinearLayout + + mRetryBtn.setOnClickListener(this) + mErrorLayout.setOnClickListener(this) + } + + override fun onClick(view: View) { + when (view.id) { + R.id.loadmore_retry, R.id.loadmore_errorlayout -> { + + showRetry(false, null) + mCallback.retryPageLoad() + } + } + } + } + + companion object { + // View Types + val ITEM = 0 + val LOADING = 1 + val HERO = 2 + + private val BASE_URL_IMG = "https://image.tmdb.org/t/p/w150" + } + +} diff --git a/app/src/main/java/com/kotlinUtils/PaginationScrollListener.kt b/app/src/main/java/com/kotlinUtils/PaginationScrollListener.kt new file mode 100644 index 0000000..6948c18 --- /dev/null +++ b/app/src/main/java/com/kotlinUtils/PaginationScrollListener.kt @@ -0,0 +1,37 @@ +package com.kotlinUtils + +import android.support.v7.widget.LinearLayoutManager +import android.support.v7.widget.RecyclerView + +/** + * Created by heinhtet on 12/9/2017. + */ + +abstract class PaginationScrollListener(manager: LinearLayoutManager): RecyclerView.OnScrollListener() { + + var layoutManager: LinearLayoutManager = manager + + override fun onScrolled(recyclerView: RecyclerView?, dx: Int, dy: Int) { + super.onScrolled(recyclerView, dx, dy) + + val visibleItemCount = layoutManager.childCount + val totalItemCount = layoutManager.itemCount + val firstVisibleItemPosition = layoutManager.findFirstVisibleItemPosition() + + if (!isLoading() && !isLastPage()) { + if (visibleItemCount + firstVisibleItemPosition >= totalItemCount && firstVisibleItemPosition >= 0) { + loadMoreItems() + } + } + } + + + protected abstract fun loadMoreItems() + + abstract fun getTotalPageCount(): Int + + abstract fun isLastPage(): Boolean + + abstract fun isLoading(): Boolean + +} \ No newline at end of file diff --git a/app/src/main/java/com/suleiman/pagination/MainActivity.java b/app/src/main/java/com/suleiman/pagination/MainActivity.java index 6f4c1cc..b1376e8 100644 --- a/app/src/main/java/com/suleiman/pagination/MainActivity.java +++ b/app/src/main/java/com/suleiman/pagination/MainActivity.java @@ -36,7 +36,7 @@ public class MainActivity extends AppCompatActivity implements PaginationAdapter private static final String TAG = "MainActivity"; - PaginationAdapter adapter; + com.kotlinUtils.PaginationAdapter adapter; LinearLayoutManager linearLayoutManager; GridLayoutManager gridLayoutManager; @@ -84,7 +84,7 @@ public void onRefresh() { } }); - adapter = new PaginationAdapter(this); + adapter = new com.kotlinUtils.PaginationAdapter(this); linearLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false); @@ -110,7 +110,7 @@ public int getSpanSize(int position) { rv.setAdapter(adapter); - rv.addOnScrollListener(new PaginationScrollListener(gridLayoutManager) { + rv.addOnScrollListener(new com.kotlinUtils.PaginationScrollListener(gridLayoutManager) { @Override protected void loadMoreItems() { isLoading = true; diff --git a/app/src/main/java/com/suleiman/pagination/utils/PaginationScrollListener.java b/app/src/main/java/com/suleiman/pagination/utils/PaginationScrollListener.java index 977330f..967f4ae 100755 --- a/app/src/main/java/com/suleiman/pagination/utils/PaginationScrollListener.java +++ b/app/src/main/java/com/suleiman/pagination/utils/PaginationScrollListener.java @@ -35,7 +35,6 @@ public void onScrolled(RecyclerView recyclerView, int dx, int dy) { loadMoreItems(); } } - } protected abstract void loadMoreItems(); diff --git a/app/src/main/res/layout/item_hero.xml b/app/src/main/res/layout/item_hero.xml index 4c65bba..6c1c05f 100644 --- a/app/src/main/res/layout/item_hero.xml +++ b/app/src/main/res/layout/item_hero.xml @@ -16,6 +16,7 @@ diff --git a/build.gradle b/build.gradle index c2eea8e..8379a6d 100644 --- a/build.gradle +++ b/build.gradle @@ -1,11 +1,13 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { + ext.kotlin_version = '1.2.0' repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:2.3.3' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files From 4a081e8a10f0e08bfb91d86ad125671433a4ed7d Mon Sep 17 00:00:00 2001 From: Hein Htet Date: Sun, 10 Dec 2017 09:14:53 +0630 Subject: [PATCH 5/9] add kotlinUtils&adapter --- .idea/modules.xml | 1 - .../com/kotlinUtils/PaginatioinAdapter.kt | 4 +- .../kotlinUtils/PaginationScrollListener.kt | 8 +++- .../com/suleiman/pagination/MainActivity.java | 42 ++++--------------- .../pagination/PaginationAdapter.java | 1 - .../utils/PaginationScrollListener.java | 3 -- app/src/main/res/layout/activity_main.xml | 6 --- 7 files changed, 16 insertions(+), 49 deletions(-) diff --git a/.idea/modules.xml b/.idea/modules.xml index 683670b..fad13b5 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -6,7 +6,6 @@ - \ No newline at end of file diff --git a/app/src/main/java/com/kotlinUtils/PaginatioinAdapter.kt b/app/src/main/java/com/kotlinUtils/PaginatioinAdapter.kt index 4140d13..bc8ca5d 100644 --- a/app/src/main/java/com/kotlinUtils/PaginatioinAdapter.kt +++ b/app/src/main/java/com/kotlinUtils/PaginatioinAdapter.kt @@ -50,7 +50,6 @@ class PaginationAdapter(private val context: Context) : RecyclerView.Adapter { val viewItem = inflater.inflate(R.layout.item_list, parent, false) @@ -186,7 +185,7 @@ class PaginationAdapter(private val context: Context) : RecyclerView.Adapter { + private fun loadImage(posterPath: String?): DrawableRequestBuilder { return Glide .with(context) .load(BASE_URL_IMG + posterPath) @@ -335,7 +334,6 @@ class PaginationAdapter(private val context: Context) : RecyclerView.Adapter { - showRetry(false, null) mCallback.retryPageLoad() } diff --git a/app/src/main/java/com/kotlinUtils/PaginationScrollListener.kt b/app/src/main/java/com/kotlinUtils/PaginationScrollListener.kt index 6948c18..a469772 100644 --- a/app/src/main/java/com/kotlinUtils/PaginationScrollListener.kt +++ b/app/src/main/java/com/kotlinUtils/PaginationScrollListener.kt @@ -2,12 +2,13 @@ package com.kotlinUtils import android.support.v7.widget.LinearLayoutManager import android.support.v7.widget.RecyclerView +import android.util.Log /** * Created by heinhtet on 12/9/2017. */ -abstract class PaginationScrollListener(manager: LinearLayoutManager): RecyclerView.OnScrollListener() { +abstract class PaginationScrollListener(manager: LinearLayoutManager) : RecyclerView.OnScrollListener() { var layoutManager: LinearLayoutManager = manager @@ -17,15 +18,18 @@ abstract class PaginationScrollListener(manager: LinearLayoutManager): RecyclerV val visibleItemCount = layoutManager.childCount val totalItemCount = layoutManager.itemCount val firstVisibleItemPosition = layoutManager.findFirstVisibleItemPosition() + Log.i(" scroll change ", "visible count " + visibleItemCount) + Log.i(" scroll change ", "total items count " + totalItemCount) + Log.i(" scroll change ", "first visible items count " + firstVisibleItemPosition) if (!isLoading() && !isLastPage()) { if (visibleItemCount + firstVisibleItemPosition >= totalItemCount && firstVisibleItemPosition >= 0) { + Log.i("scroll load more items","") loadMoreItems() } } } - protected abstract fun loadMoreItems() abstract fun getTotalPageCount(): Int diff --git a/app/src/main/java/com/suleiman/pagination/MainActivity.java b/app/src/main/java/com/suleiman/pagination/MainActivity.java index b1376e8..bbdc7a3 100644 --- a/app/src/main/java/com/suleiman/pagination/MainActivity.java +++ b/app/src/main/java/com/suleiman/pagination/MainActivity.java @@ -1,10 +1,8 @@ package com.suleiman.pagination; -import android.annotation.SuppressLint; import android.content.Context; import android.net.ConnectivityManager; import android.os.Bundle; -import android.support.v4.widget.SwipeRefreshLayout; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.DefaultItemAnimator; import android.support.v7.widget.GridLayoutManager; @@ -16,7 +14,6 @@ import android.widget.LinearLayout; import android.widget.ProgressBar; import android.widget.TextView; -import android.widget.Toast; import com.suleiman.pagination.api.MovieApi; import com.suleiman.pagination.api.MovieService; @@ -36,7 +33,7 @@ public class MainActivity extends AppCompatActivity implements PaginationAdapter private static final String TAG = "MainActivity"; - com.kotlinUtils.PaginationAdapter adapter; + PaginationAdapter adapter; LinearLayoutManager linearLayoutManager; GridLayoutManager gridLayoutManager; @@ -45,7 +42,6 @@ public class MainActivity extends AppCompatActivity implements PaginationAdapter LinearLayout errorLayout; Button btnRetry; TextView txtError; - SwipeRefreshLayout swipeRefreshLayout; private static final int PAGE_START = 1; @@ -58,7 +54,6 @@ public class MainActivity extends AppCompatActivity implements PaginationAdapter private MovieService movieService; - @SuppressLint("ResourceAsColor") @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -69,22 +64,8 @@ protected void onCreate(Bundle savedInstanceState) { errorLayout = (LinearLayout) findViewById(R.id.error_layout); btnRetry = (Button) findViewById(R.id.error_btn_retry); txtError = (TextView) findViewById(R.id.error_txt_cause); - swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_layout); - swipeRefreshLayout.setColorScheme(android.R.color.holo_green_light, - android.R.color.holo_orange_light, - android.R.color.holo_red_light); - - swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { - @Override - public void onRefresh() { - adapter.clear(); - currentPage = PAGE_START; - loadApi("first"); - } - }); - - adapter = new com.kotlinUtils.PaginationAdapter(this); + adapter = new PaginationAdapter(this); linearLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false); @@ -95,11 +76,11 @@ public void onRefresh() { public int getSpanSize(int position) { switch (adapter.getItemViewType(position)) { case PaginationAdapter.HERO: - return 2; // spacing 2 row in 1 items + return 2; case PaginationAdapter.ITEM: - return 1; // spacing 1 row in 1 items + return 1; case PaginationAdapter.LOADING: - return 2;// spacing 2 row in 1 items + return 2; default: return -1; } @@ -116,6 +97,7 @@ protected void loadMoreItems() { isLoading = true; currentPage += 1; loadApi("next"); + Log.d("load more ", "call back"); } @Override @@ -161,7 +143,7 @@ public void onResponse(Call call, Response respo // Got data. Send it to adapter hideErrorView(); - hideSwifeRefresh(); + List results = fetchResults(response); progressBar.setVisibility(View.GONE); adapter.addAll(results); @@ -178,10 +160,6 @@ public void onFailure(Call call, Throwable t) { }); } - private void hideSwifeRefresh() { - swipeRefreshLayout.setRefreshing(false); - } - /** * @param response extracts List<{@link Result>} from response * @return @@ -226,7 +204,6 @@ public void onResponse(Call call, Response respo if (type.equals("first")) { Log.d(TAG, "loadFirstPage: " + currentPage); hideErrorView(); - hideSwifeRefresh(); List results = fetchResults(response); progressBar.setVisibility(View.GONE); adapter.addAll(results); @@ -273,13 +250,12 @@ public void retryPageLoad() { @Override public void onItemsClickListener(Result result, int position) { - adapter.removeAtItemsPosition(position); - Toast.makeText(this, "You click " + position + " items " + result.getTitle(), Toast.LENGTH_SHORT).show(); + } @Override public void emptyLayout() { - Toast.makeText(this, "empty items", Toast.LENGTH_SHORT).show(); + } diff --git a/app/src/main/java/com/suleiman/pagination/PaginationAdapter.java b/app/src/main/java/com/suleiman/pagination/PaginationAdapter.java index 727746c..48f3cdf 100644 --- a/app/src/main/java/com/suleiman/pagination/PaginationAdapter.java +++ b/app/src/main/java/com/suleiman/pagination/PaginationAdapter.java @@ -131,7 +131,6 @@ public boolean onResourceReady(GlideDrawable resource, String model, Target - - \ No newline at end of file From e0afc79f7c5db4a2cb3f575cd4c27d00b2714945 Mon Sep 17 00:00:00 2001 From: Hein Htet Date: Sun, 10 Dec 2017 09:16:22 +0630 Subject: [PATCH 6/9] add kotlinUtils&adapter --- app/src/main/java/com/suleiman/pagination/MainActivity.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/src/main/java/com/suleiman/pagination/MainActivity.java b/app/src/main/java/com/suleiman/pagination/MainActivity.java index bbdc7a3..57d012b 100644 --- a/app/src/main/java/com/suleiman/pagination/MainActivity.java +++ b/app/src/main/java/com/suleiman/pagination/MainActivity.java @@ -198,6 +198,11 @@ public void onFailure(Call call, Throwable t) { /*adding type and call api method write once*/ private void loadApi(final String type) { + + if (type.equals("first")) { + hideErrorView(); + } + callTopRatedMoviesApi().enqueue(new Callback() { @Override public void onResponse(Call call, Response response) { From 979a343ce7090acdef76fe682c5cc665ea14e7f7 Mon Sep 17 00:00:00 2001 From: Hein Htet Date: Sun, 10 Dec 2017 12:54:40 +0630 Subject: [PATCH 7/9] add update specific row --- .../com/kotlinUtils/PaginatioinAdapter.kt | 30 +++++++++-- .../com/suleiman/pagination/MainActivity.java | 51 ++++++++++++++++--- app/src/main/res/layout/activity_main.xml | 6 +++ app/src/main/res/layout/item_hero.xml | 17 ++++--- app/src/main/res/layout/item_list.xml | 20 ++++---- app/src/main/res/values/colors.xml | 2 +- app/src/main/res/values/strings.xml | 2 +- app/src/main/res/values/styles.xml | 3 +- 8 files changed, 98 insertions(+), 33 deletions(-) diff --git a/app/src/main/java/com/kotlinUtils/PaginatioinAdapter.kt b/app/src/main/java/com/kotlinUtils/PaginatioinAdapter.kt index bc8ca5d..b6e479d 100644 --- a/app/src/main/java/com/kotlinUtils/PaginatioinAdapter.kt +++ b/app/src/main/java/com/kotlinUtils/PaginatioinAdapter.kt @@ -176,7 +176,6 @@ class PaginationAdapter(private val context: Context) : RecyclerView.Adapter { + + if (posterPath != null) { + if (posterPath.contains("profile_image")) { + imageUrl = posterPath + } else { + imageUrl = BASE_URL_IMG + posterPath + } + } else { + imageUrl = BASE_URL_IMG + posterPath + } + return Glide .with(context) - .load(BASE_URL_IMG + posterPath) + .load(imageUrl) .diskCacheStrategy(DiskCacheStrategy.ALL) // cache both original & resized image .centerCrop() .crossFade() } - /* Helpers - Pagination _________________________________________________________________________________________________ @@ -232,6 +243,14 @@ class PaginationAdapter(private val context: Context) : RecyclerView.Adapter call, Response response) { if (type.equals("first")) { + hideSwipeRefresh(); Log.d(TAG, "loadFirstPage: " + currentPage); hideErrorView(); List results = fetchResults(response); @@ -227,7 +234,11 @@ public void onResponse(Call call, Response respo @Override public void onFailure(Call call, Throwable t) { t.printStackTrace(); - adapter.showRetry(true, fetchErrorMessage(t)); + if (type.equals("first")) { + showErrorView(t); + } else { + adapter.showRetry(true, fetchErrorMessage(t)); + } } }); } @@ -255,7 +266,18 @@ public void retryPageLoad() { @Override public void onItemsClickListener(Result result, int position) { - + Toast.makeText(this, "click position " + position, Toast.LENGTH_SHORT).show(); + Result result1 = new Result(); + result1.setId(19); + result1.setAdult(true); + result1.setOriginalLanguage("MM"); + result1.setOriginalTitle(""); + result1.setReleaseDate("1993"); + result1.setBackdropPath("https://pbs.twimg.com/profile_images/737889751034920960/ATs6TR-T_400x400.jpg"); + result1.setPosterPath("https://pbs.twimg.com/profile_images/737889751034920960/ATs6TR-T_400x400.jpg"); + result1.setTitle("Hein Htet"); + result1.setGenreIds(new ArrayList()); + adapter.updateItemsAtPosition(position, result1); } @Override @@ -263,6 +285,12 @@ public void emptyLayout() { } + private void hideSwipeRefresh() { + if (swipeRefreshLayout.isRefreshing()) { + swipeRefreshLayout.setRefreshing(false); + } + } + /** * @param throwable required for {@link #fetchErrorMessage(Throwable)} @@ -271,9 +299,9 @@ public void emptyLayout() { private void showErrorView(Throwable throwable) { if (errorLayout.getVisibility() == View.GONE) { + hideSwipeRefresh(); errorLayout.setVisibility(View.VISIBLE); progressBar.setVisibility(View.GONE); - txtError.setText(fetchErrorMessage(throwable)); } } @@ -313,4 +341,11 @@ private boolean isNetworkConnected() { ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); return cm.getActiveNetworkInfo() != null; } + + @Override + public void onRefresh() { + currentPage = PAGE_START; + adapter.clear(); + loadApi("first"); + } } diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 94f83bc..77d5da9 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,4 +1,8 @@ + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_hero.xml b/app/src/main/res/layout/item_hero.xml index 6c1c05f..7329358 100644 --- a/app/src/main/res/layout/item_hero.xml +++ b/app/src/main/res/layout/item_hero.xml @@ -1,6 +1,5 @@ - + android:adjustViewBounds="true" + android:foreground="?attr/selectableItemBackground" + tools:background="@color/colorAccent" /> + android:background="@drawable/scrim" /> + tools:text="Doctor Who : The Day of the Doctor" /> + tools:text="2009 | EN" /> @@ -73,7 +74,7 @@ android:ellipsize="end" android:maxLines="2" android:textColor="@android:color/white" - tools:text="Nowadays, user engagement is considered one of the most important metrics for the success of your app"/> + tools:text="Nowadays, user engagement is considered one of the most important metrics for the success of your app" /> diff --git a/app/src/main/res/layout/item_list.xml b/app/src/main/res/layout/item_list.xml index 7f1a783..c99c19c 100644 --- a/app/src/main/res/layout/item_list.xml +++ b/app/src/main/res/layout/item_list.xml @@ -1,10 +1,10 @@ + xmlns:app="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:orientation="vertical"> + android:theme="@style/CircularProgress" /> + android:layout_height="@dimen/poster_thumb_height" /> @@ -54,7 +54,7 @@ android:gravity="end" android:maxLines="1" android:textStyle="bold" - tools:text="2009 | EN"/> + tools:text="2009 | EN" /> + tools:text="Movie Title" /> + tools:text="Nowadays, user engagement is considered one of the most important metrics for the success of your app" /> diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 46cf8ff..a3997c4 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -1,6 +1,6 @@ - #5F4BB6 + #030303 #433582 #26F0F1 #EFEFEF diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 5b87003..b970216 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,5 +1,5 @@ - Pagination + Recycler View Paginate and More ec01f8c2eb6ac402f2ca026dc2d9b8fd Sorry! Couldn\'t fetch movies. Retry diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 694e6b7..a8c06d7 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -1,4 +1,4 @@ - +