Skip to content

Instantly share code, notes, and snippets.

@sidhuparas
Created July 15, 2018 08:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sidhuparas/e34587a4a16a288711a0edba1c0ea935 to your computer and use it in GitHub Desktop.
Save sidhuparas/e34587a4a16a288711a0edba1c0ea935 to your computer and use it in GitHub Desktop.
movies_arch_comp
import android.app.Activity;
import android.app.Application;
import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.chip.Chip;
import android.support.v4.app.ActivityOptionsCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.Toast;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import com.facebook.stetho.Stetho;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.parassidhu.popularmovies.BuildConfig;
import com.parassidhu.popularmovies.R;
import com.parassidhu.popularmovies.adapters.MoviesAdapter;
import com.parassidhu.popularmovies.database.MovieDatabase;
import com.parassidhu.popularmovies.models.MovieItem;
import com.parassidhu.popularmovies.utils.Constants;
import com.parassidhu.popularmovies.utils.ItemClickSupport;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;
public class MainActivity extends AppCompatActivity {
@BindView(R.id.moviesList) RecyclerView moviesList;
@BindView(R.id.toolbar) Toolbar toolbar;
@BindView(R.id.progressBar) ProgressBar progressBar;
@BindView(R.id.popular) Chip popular;
@BindView(R.id.top_rated) Chip top_rated;
private ArrayList<MovieItem> moviesItems = new ArrayList<>();
private GridLayoutManager mLayoutManager;
private MoviesAdapter adapter;
private int pageNum;
private String sortBy; // Stores user-selected URL, Popular Movies or Top-Rated
private MovieViewModel mViewModel;
private MovieDatabase mDb;
private String TAG = getClass().getSimpleName();
public static final String MOVIE_KEY = "movie_item";
private Comparator<MovieItem> comparator = new Comparator<MovieItem>() {
@Override
public int compare(MovieItem movieItem, MovieItem t1) {
Double d = Double.valueOf(movieItem.getPopularity())
- Double.valueOf(t1.getPopularity());
if (d > 0) return -1;
else if (d == 0) return 0;
else return 1;
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
init();
sortBy = Constants.POPULAR_LIST;
setupViewModel();
// fetchMovies(getURL(pageNum));
popular.setSelected(true);
}
// Basic setup of views
private void init() {
Stetho.initializeWithDefaults(this);
mDb = MovieDatabase.getDatabase(this);
// Setup RecyclerView
int spanCount = 2;
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
spanCount = 3;
}
pageNum = 1;
mLayoutManager = new GridLayoutManager(this, spanCount);
moviesList.setLayoutManager(mLayoutManager);
// Setup Custom Toolbar
setSupportActionBar(toolbar);
setTitle("");
// Show progress bar and hide list
//controlViews(true, false);
//Set Listeners
setChipListeners();
setMovieClickListener();
addListScrollListener();
}
// Handle ViewModel
private void setupViewModel() {
mViewModel = ViewModelProviders.of(this).get(MovieViewModel.class);
mViewModel.getAllMovies().observe(this, new Observer<List<MovieItem>>() {
@Override
public void onChanged(@Nullable List<MovieItem> movieItems) {
if (isOnline()){
fetchMovies(getURL(pageNum));
} else {
showInUI(movieItems);
}
}
});
}
private void showInUI(List<MovieItem> movieItems) {
Log.d(TAG, "onChanged: Notified: " + movieItems.size());
if (movieItems.size() != 0) { // Activity was destroyed and re-created
if (moviesList.getAdapter() == null) {
adapter = new MoviesAdapter(MainActivity.this,
new ArrayList<>(movieItems));
moviesList.setAdapter(adapter);
} else {
adapter.notifyDataSetChanged();
}
} else { // Activity is started for the first time
fetchMovies(getURL(pageNum));
Log.d(TAG, "showInUI: Loading new...");
}
}
private void addListScrollListener() {
moviesList.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
// Total Items
int count = mLayoutManager.getItemCount();
if ((dy > 0) && (count / 20 == pageNum)) {
int holderCount = mLayoutManager.getChildCount();
int oldCount = mLayoutManager.findFirstVisibleItemPosition();
// Checks if user is on the verge of end of the list
if (holderCount + oldCount >= (count - 10)) {
// Increments the page number and fetch the result
pageNum++;
fetchMovies(getURL(pageNum));
}
}
}
});
}
private String getURL(int page) {
Uri uri = Uri.parse(sortBy).buildUpon()
.appendQueryParameter("api_key", BuildConfig.API_KEY)
.appendQueryParameter("page", String.valueOf(page))
.build();
return uri.toString();
}
// Fetch JSON from the API
private void fetchMovies(String URL) {
if (pageNum == 1) {
//controlViews(true, false);
}
StringRequest stringRequest = new StringRequest(Request.Method.GET, URL,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
parseAndShowInUi(response);
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
controlViews(false, false);
showError();
}
});
stringRequest.setShouldCache(false);
RequestQueue requestQueue = Volley.newRequestQueue(this.getApplicationContext());
requestQueue.add(stringRequest);
}
// Parse the response and show to the main user interface
private void parseAndShowInUi(String response) {
try {
JSONObject jsonObject = new JSONObject(response);
JSONArray jsonArray = jsonObject.optJSONArray("results");
if (jsonArray.length() > 0) {
Gson gson = new Gson();
// Creates a new ArrayList of fetched result
ArrayList<MovieItem> items = new ArrayList<>();
for (int i = 0; i < jsonArray.length(); i++) {
MovieItem item = gson.fromJson(jsonArray.optJSONObject(i).toString(),
MovieItem.class);
item.setSortBy(sortBy);
items.add(item);
}
// Adds the above ArrayList to main ArrayList which is
// to be passed
moviesItems.addAll(items);
mViewModel.insertMovies(moviesItems);
if (moviesList.getAdapter() == null) {
adapter = new MoviesAdapter(MainActivity.this,
moviesItems);
moviesList.setAdapter(adapter);
} else {
adapter.notifyDataSetChanged();
}
Log.d(TAG, "parseAndShowInUi: Done");
controlViews(false, true);
Log.d(TAG, "parseAndShowInUi: Hidden");
}
} catch (JSONException e) {
Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();
showError();
controlViews(false, false);
}
}
private void showError() {
Toast.makeText(MainActivity.this,
"Please retry after some time!", Toast.LENGTH_SHORT).show();
}
private boolean isOnline(){
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = cm.getActiveNetworkInfo();
return networkInfo!=null && networkInfo.isConnected();
}
// Sets listener for individual movie click
private void setMovieClickListener() {
ItemClickSupport.addTo(moviesList).setOnItemClickListener(new ItemClickSupport.OnItemClickListener() {
@Override
public void onItemClicked(RecyclerView recyclerView, int position, View v) {
Intent intent = new Intent(MainActivity.this, MovieActivity.class);
Bundle bundle = new Bundle();
MovieItem item = moviesItems.get(position);
bundle.putParcelable(MOVIE_KEY, item);
intent.putExtra("Values", bundle);
// Shared Element Transition
ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation(
MainActivity.this, v, getResources().getString(R.string.img_trans));
startActivity(intent, options.toBundle());
}
});
}
// Set listener for click of "Popular" or "Top Rated"
private void setChipListeners() {
popular.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
controlChip(true, false);
sortBy = Constants.POPULAR_LIST;
moviesItems.clear();
pageNum = 1;
fetchMovies(getURL(pageNum));
}
});
top_rated.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
controlChip(false, true);
sortBy = Constants.TOP_RATED_LIST;
moviesItems.clear();
pageNum = 1;
fetchMovies(getURL(pageNum));
}
});
}
// Helper method
private void controlViews(boolean progress, boolean list) {
if (progress) {
progressBar.setVisibility(View.VISIBLE);
} else {
progressBar.setVisibility(View.GONE);
}
if (list) {
moviesList.setVisibility(View.VISIBLE);
} else {
//moviesList.setVisibility(View.GONE);
}
}
// Helper method
private void controlChip(boolean pop, boolean toprated) {
if (pop) {
popular.setSelected(true);
} else {
popular.setSelected(false);
}
if (toprated) {
top_rated.setSelected(true);
} else {
top_rated.setSelected(false);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment