com.nasahapps.awkwardratings.ui.MainActivity.java Source code

Java tutorial

Introduction

Here is the source code for com.nasahapps.awkwardratings.ui.MainActivity.java

Source

/*
 * Copyright (c) 2015 Nasah Apps
 */

package com.nasahapps.awkwardratings.ui;

import android.annotation.TargetApi;
import android.app.ActivityOptions;
import android.app.AlertDialog;
import android.app.SearchManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.Point;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.view.MenuItemCompat;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.graphics.Palette;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.SearchView;
import android.support.v7.widget.Toolbar;
import android.transition.Explode;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.malinskiy.superrecyclerview.OnMoreListener;
import com.malinskiy.superrecyclerview.SuperRecyclerView;
import com.nasahapps.awkwardratings.AnalyticsHelper;
import com.nasahapps.awkwardratings.PreferencesHelper;
import com.nasahapps.awkwardratings.R;
import com.nasahapps.awkwardratings.Utils;
import com.nasahapps.awkwardratings.model.Movie;
import com.nasahapps.awkwardratings.model.MovieRating;
import com.nasahapps.awkwardratings.service.NetworkHelper;
import com.nasahapps.awkwardratings.service.VoteHelper;
import com.nasahapps.awkwardratings.service.response.MovieResponse;
import com.nasahapps.awkwardratings.ui.custom.HidingScrollListener;
import com.parse.FindCallback;
import com.parse.GetCallback;
import com.parse.ParseException;
import com.parse.ParseObject;
import com.parse.ParseQuery;
import com.parse.SaveCallback;
import com.squareup.picasso.Callback;
import com.squareup.picasso.Picasso;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import de.greenrobot.event.EventBus;
import de.psdev.licensesdialog.LicensesDialog;
import jp.wasabeef.recyclerview.animators.adapters.AlphaInAnimationAdapter;
import jp.wasabeef.recyclerview.animators.adapters.ScaleInAnimationAdapter;
import jp.wasabeef.recyclerview.animators.adapters.SlideInBottomAnimationAdapter;
import retrofit.RetrofitError;

public class MainActivity extends ActionBarActivity {

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

    @TargetApi(21)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        if (Utils.isAtApiLevel(21)) {
            // Set window transitions for when user clicks a movie
            getWindow().setAllowEnterTransitionOverlap(true);
            getWindow().setAllowReturnTransitionOverlap(true);
            getWindow().setExitTransition(new Explode());
        }
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity);
        if (savedInstanceState == null) {
            getSupportFragmentManager().beginTransaction().add(R.id.container, new MainFragment()).commit();
        }

        AnalyticsHelper.getInstance(this).sendScreenViewAnalytics("Main page");
    }

    public static class MainFragment extends Fragment {

        private SuperRecyclerView mRecyclerView;
        private List<ParseObject> mMovies = new ArrayList<>();
        private Map<Integer, MovieRating> mMovieRatings;
        private Toolbar mToolbar;
        // For when we return from MovieActivity, we know which view in RecyclerView to
        // refresh in case user voted on that page
        private int mLastPosition, mRateCounter;
        // Using a ListView instead of RecyclerView because I've had problems in the past
        // with RecyclerViews crashing whenever its parent layout in XML has
        // android:animateLayoutChanges="true". ListViews don't have this problem
        // Plus, we'll only be showing at most 20 movies per search query so
        // large scale lists are not a problem here
        private ListView mSearchListView;
        private List<Movie> mSearchedMovies;
        private Menu mMenu;
        private String mLastQuery;
        // List of choices to sort movie results by
        private String[] mSortChoices = new String[] { "Last updated", "Awkwardness ascending",
                "Awkwardness descending", "A - Z", "Z - A" };
        private Button mRefresh;

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            View v = inflater.inflate(R.layout.fragment_main, container, false);
            // So the fragment isn't recreated on rotation
            setRetainInstance(true);
            // And we attach a menu for this fragment
            setHasOptionsMenu(true);

            // To implement the hiding ActionBar, we must have the style of this fragment's
            // Activity not have an ActionBar and put in a Toolbar in the xml layout so we can
            // manually show/hide the Toolbar as the user scrolls through the list of movies
            mToolbar = (Toolbar) v.findViewById(R.id.toolbar);
            ((ActionBarActivity) getActivity()).setSupportActionBar(mToolbar);

            mRecyclerView = (SuperRecyclerView) v.findViewById(R.id.list);
            // When in portrait
            if (Utils.isPortrait(getActivity())) {
                // Phones laid out as a list
                if (!Utils.isTablet(getActivity())) {
                    mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
                } else { // Tablets in a grid of 2 columns
                    mRecyclerView.setLayoutManager(new GridLayoutManager(getActivity(), 2));
                    // Also have the refresh view be large
                    mRecyclerView.getSwipeToRefresh().setSize(SwipeRefreshLayout.LARGE);
                }
            } else {
                // When in landscape, a horizontal list
                mRecyclerView.setLayoutManager(
                        new LinearLayoutManager(getActivity(), LinearLayoutManager.HORIZONTAL, false));
            }
            // Our scroll listener to have it hide/show the Toolbar on scroll
            mRecyclerView.setOnScrollListener(new HidingScrollListener() {
                @Override
                public void onHide() {
                    mToolbar.animate().translationY(-mToolbar.getHeight())
                            .setInterpolator(new AccelerateInterpolator(2));
                }

                @Override
                public void onShow() {
                    mToolbar.animate().translationY(0).setInterpolator(new DecelerateInterpolator(2));
                }
            });
            // Pull down to refresh list of movies
            // Only available in portrait since in landscape you swipe left-right, not up-down
            if (Utils.isPortrait(getActivity())) {
                mRecyclerView.setRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
                    @Override
                    public void onRefresh() {
                        getMovies();
                    }
                });
            }
            // And have a colorful spinning refresh animation
            mRecyclerView.setRefreshingColorResources(android.R.color.holo_orange_light,
                    android.R.color.holo_blue_light, android.R.color.holo_green_light,
                    android.R.color.holo_red_light);
            // And have it not hidden under the Toolbar
            mRecyclerView.getSwipeToRefresh().setProgressViewOffset(false,
                    (int) Utils.dpToPixel(getResources(), 24), (int) Utils.dpToPixel(getResources(), 24 + 48));
            // When 10 items away from the end of the list, query for more
            mRecyclerView.setupMoreListener(new OnMoreListener() {
                @Override
                public void onMoreAsked(int numOfItems, int numBeforeMore, int currentItemPos) {
                    getMovies();
                }
            }, 10);
            // Also, set the adapter if we already have movies (used if device was rotated)
            if (savedInstanceState != null) {
                MovieAdapter adapter = new MovieAdapter(mMovies);
                // Scale in, alpha in, and slide in from bottom new items
                mRecyclerView.setAdapter(new SlideInBottomAnimationAdapter(
                        new ScaleInAnimationAdapter(new AlphaInAnimationAdapter(adapter))));
            }

            // The ListView holding our search results
            mSearchListView = (ListView) v.findViewById(R.id.searchListView);
            // Repopulate the listview if user rotated the device
            // On rotation, mSearchedMovies is retained and thus if it wasn't null before rotation,
            // it won't be null after rotation
            if (mSearchedMovies != null) {
                SearchMovieAdapter adapter = new SearchMovieAdapter(getActivity(), mSearchedMovies);
                mSearchListView.setAdapter(adapter);
                mSearchListView.setVisibility(View.VISIBLE);
            }
            mSearchListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    // When item is clicked, first check if the movie the user wants to see is in our
                    // Parse DB
                    final Movie m = mSearchedMovies.get(position);
                    ParseQuery<ParseObject> query = ParseQuery.getQuery("Movie");
                    query.whereEqualTo("movie_id", m.getId());
                    query.getFirstInBackground(new GetCallback<ParseObject>() {
                        @Override
                        public void done(ParseObject parseObject, ParseException e) {
                            if (e == null) {
                                // Not sure if no object would return a null ParseObject or
                                // return a ParseException saying no results returned. So
                                // implementing for both cases
                                if (parseObject != null) {
                                    // We have this movie in our database, open this movie's page
                                    Intent i = new Intent(getActivity(), MovieActivity.class);
                                    i.putExtra(MovieActivity.EXTRA_ID, m.getId());
                                    startActivity(i);
                                } else {
                                    // Add this movie to our database so users can vote on it
                                    ParseObject movie = new ParseObject("Movie");
                                    movie.put("adult", m.isAdult());
                                    movie.put("backdrop_path", m.getBackdropPath());
                                    movie.put("movie_id", m.getId());
                                    movie.put("original_title", m.getOriginalTitle());
                                    movie.put("release_date", m.getReleaseDate());
                                    movie.put("poster_path", m.getPosterPath());
                                    movie.put("title", m.getTitle());
                                    movie.saveInBackground(new SaveCallback() {
                                        @TargetApi(21)
                                        @Override
                                        public void done(ParseException e) {
                                            // If everything went well, then open up the movie page
                                            if (e == null) {
                                                Intent i = new Intent(getActivity(), MovieActivity.class);
                                                i.putExtra(MovieActivity.EXTRA_ID, m.getId());
                                                if (Utils.isAtApiLevel(21)) {
                                                    // Call this version of startActivity to allow the transition animations
                                                    // to happen
                                                    getActivity().startActivity(i,
                                                            ActivityOptions
                                                                    .makeSceneTransitionAnimation(getActivity())
                                                                    .toBundle());
                                                } else {
                                                    startActivity(i);
                                                }
                                            } else {
                                                Utils.showError(getActivity(), TAG, "Error saving new movie", e,
                                                        e.getLocalizedMessage());
                                            }
                                        }
                                    });
                                }
                            } else {
                                Log.e(TAG, "Error querying movies", e);
                                // Add this movie to our database so users can vote on it
                                ParseObject movie = new ParseObject("Movie");
                                movie.put("adult", m.isAdult());
                                if (m.getBackdropPath() != null)
                                    movie.put("backdrop_path", m.getBackdropPath());
                                movie.put("movie_id", m.getId());
                                if (m.getOriginalTitle() != null)
                                    movie.put("original_title", m.getOriginalTitle());
                                if (m.getReleaseDate() != null)
                                    movie.put("release_date", m.getReleaseDate());
                                if (m.getPosterPath() != null)
                                    movie.put("poster_path", m.getPosterPath());
                                if (m.getTitle() != null)
                                    movie.put("title", m.getTitle());
                                movie.saveInBackground(new SaveCallback() {
                                    @TargetApi(21)
                                    @Override
                                    public void done(ParseException e) {
                                        // If everything went well, then open up the movie page
                                        if (e == null) {
                                            Intent i = new Intent(getActivity(), MovieActivity.class);
                                            i.putExtra(MovieActivity.EXTRA_ID, m.getId());
                                            if (Utils.isAtApiLevel(21)) {
                                                // Call this version of startActivity to allow the transition animations
                                                // to happen
                                                getActivity().startActivity(i, ActivityOptions
                                                        .makeSceneTransitionAnimation(getActivity()).toBundle());
                                            } else {
                                                startActivity(i);
                                            }
                                        } else {
                                            Utils.showError(getActivity(), TAG, "Error saving new movie", e,
                                                    e.getLocalizedMessage());
                                        }
                                    }
                                });
                            }
                        }
                    });
                }
            });

            mRefresh = (Button) mRecyclerView.getEmptyView().findViewById(R.id.refresh);
            mRefresh.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    mRecyclerView.getEmptyView().setVisibility(View.INVISIBLE);
                    mRecyclerView.getSwipeToRefresh().setRefreshing(true);
                    getMovies();
                }
            });

            mRateCounter = PreferencesHelper.getInstance(getActivity())
                    .getInt(PreferencesHelper.KEY_RATE_APP_COUNTER, 0);
            mRateCounter++;
            PreferencesHelper.getInstance(getActivity()).putInt(PreferencesHelper.KEY_RATE_APP_COUNTER,
                    mRateCounter);
            Utils.showRateDialog(getActivity(), mRateCounter);

            EventBus.getDefault().register(this);

            // Only get movies if this is the first time loading (not after rotation)
            if (savedInstanceState == null) {
                // Also load user's movie ratings from prefs
                mMovieRatings = PreferencesHelper.getInstance(getActivity()).loadMovieRatings();
                getMovies();
            }

            return v;
        }

        @Override
        public void onStart() {
            super.onStart();
            if (!EventBus.getDefault().isRegistered(this))
                EventBus.getDefault().register(this);
        }

        @Override
        public void onResume() {
            super.onResume();
            // When coming back from a movie page, refresh the recycler view in case any votes
            // were changed
            mMovieRatings = PreferencesHelper.getInstance(getActivity()).loadMovieRatings();
            if (mRecyclerView != null && mRecyclerView.getAdapter() != null) {
                mRecyclerView.getAdapter().notifyItemChanged(mLastPosition);
            }
        }

        @Override
        public void onStop() {
            super.onStop();
            if (EventBus.getDefault().isRegistered(this))
                EventBus.getDefault().unregister(this);
        }

        @Override
        public void onPrepareOptionsMenu(Menu menu) {
            // If user was searching and rotated, make sure the search bar is still expanded
            if (mMenu != null && mSearchedMovies != null) {
                MenuItem searchItem = mMenu.findItem(R.id.searchMenuItem);
                searchItem.expandActionView();
                SearchView searchView = (SearchView) menu.findItem(R.id.searchMenuItem).getActionView();
                searchView.setQuery(mLastQuery, false);
            }
            super.onPrepareOptionsMenu(menu);
        }

        @Override
        public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
            // Inflate the options menu from XML
            inflater.inflate(R.menu.menu_main, menu);
            mMenu = menu;

            // Get the SearchView and set the searchable config
            if (getActivity() != null) {
                SearchManager searchManager = (SearchManager) getActivity()
                        .getSystemService(Context.SEARCH_SERVICE);
                final SearchView searchView = (SearchView) menu.findItem(R.id.searchMenuItem).getActionView();
                searchView.setSearchableInfo(searchManager.getSearchableInfo(getActivity().getComponentName()));
                searchView.setIconifiedByDefault(true); // Show as an icon by default
                searchView.setQueryHint("Search movies"); // For some reason, setting this in xml doesn't work
                searchView.setQuery(mLastQuery, false); // If user rotated, pre-fill the search bar with
                // the user's last query
                // Also side note, when the user presses the "return" key on the keyboard, this doesn't
                // do a search simply because a search is already being done as they type. Pressing "return"
                // just hides the keyboard if it's showing

                MenuItem searchItem = menu.findItem(R.id.searchMenuItem);
                // This was added because some devices wouldn't get rid of the SearchListView
                // when the back button was clicked. This fixes that.
                MenuItemCompat.setOnActionExpandListener(searchItem, new MenuItemCompat.OnActionExpandListener() {
                    @Override
                    public boolean onMenuItemActionExpand(MenuItem menuItem) {
                        mSearchListView.setVisibility(View.VISIBLE);
                        return true;
                    }

                    @Override
                    public boolean onMenuItemActionCollapse(MenuItem menuItem) {
                        mSearchListView.setAdapter(null);
                        mSearchListView.setVisibility(View.GONE);
                        mSearchedMovies = null;
                        return true;
                    }
                });
                searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
                    @Override
                    public boolean onQueryTextSubmit(String s) {
                        return false;
                    }

                    @Override
                    public boolean onQueryTextChange(String s) {
                        if (s.equals("")) {
                            mSearchListView.setAdapter(null);
                        } else {
                            mLastQuery = s;
                            NetworkHelper.getInstance(getActivity()).searchMovie(s);
                        }

                        return true;
                    }
                });
            }

            super.onCreateOptionsMenu(menu, inflater);
        }

        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
            switch (item.getItemId()) {
            case R.id.github:
                // Open the Github to view this app's source code
                Intent i = new Intent(Intent.ACTION_VIEW);
                i.setData(Uri.parse("https://github.com/nasahapps/AwkwardRatings-Android"));
                if (i.resolveActivity(getActivity().getPackageManager()) != null) {
                    startActivity(i);
                } else {
                    Toast.makeText(getActivity(), "No web browser installed", Toast.LENGTH_SHORT).show();
                }
                return true;
            case R.id.openSource:
                // Open a dialog to give credit to 3rd-party libraries
                new LicensesDialog.Builder(getActivity()).setNotices(R.raw.notices).build().show();
                return true;
            case R.id.sort:
                // Open a dialog to figure out how to sort results
                final int sortChoice = PreferencesHelper.getInstance(getActivity())
                        .getInt(PreferencesHelper.KEY_SORT, 0);
                AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
                builder.setTitle("Sort Movies")
                        .setSingleChoiceItems(mSortChoices, sortChoice, new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                if (which != sortChoice) {
                                    // Save the new sorting preference
                                    PreferencesHelper.getInstance(getActivity()).putInt(PreferencesHelper.KEY_SORT,
                                            which);
                                    // Clear our list of movies
                                    mMovies.clear();
                                    if (mRecyclerView.getAdapter() != null)
                                        mRecyclerView.getAdapter().notifyDataSetChanged();
                                    mRecyclerView.getEmptyView().setVisibility(View.INVISIBLE);
                                    mRecyclerView.getSwipeToRefresh().setRefreshing(true);
                                    // And re-query movies with the new sorting preference
                                    getMovies();
                                }
                                // Dismiss the dialog
                                dialog.dismiss();
                            }
                        }).setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {

                            }
                        });
                builder.create().show();
            default:
                return super.onOptionsItemSelected(item);
            }
        }

        /**
         * For getting movies from our Parse DB
         */
        public void getMovies() {
            // Query our db for the movies
            ParseQuery<ParseObject> query = ParseQuery.getQuery("Movie");
            switch (PreferencesHelper.getInstance(getActivity()).getInt(PreferencesHelper.KEY_SORT, 0)) {
            case 0:
                // Sort by last updated
                query.orderByDescending("updatedAt");
                break;
            case 1:
                // Sort by awkwardness ascending
                query.orderByAscending("awkwardness");
                break;
            case 2:
                // Sort by awkwardness descending
                query.orderByDescending("awkwardness");
                break;
            case 3:
                // Sort alphabetically
                query.orderByAscending("title");
                break;
            case 4:
                // Sort backwards alphabetically
                query.orderByDescending("title");
                break;
            default:
                // Sort by last updated
                query.orderByDescending("updatedAt");
            }
            // For pagination
            query.setSkip(mMovies.size());
            // Get 1000 at a time
            query.setLimit(1000);
            query.findInBackground(new FindCallback<ParseObject>() {
                @Override
                public void done(List<ParseObject> parseObjects, ParseException e) {
                    mRecyclerView.hideMoreProgress();
                    mRecyclerView.getSwipeToRefresh().setRefreshing(false);

                    if (e == null) {
                        if (mMovies.isEmpty()) {
                            // Create a new adapter to bind to our RecyclerView
                            mMovies.addAll(parseObjects);
                            MovieAdapter adapter = new MovieAdapter(mMovies);
                            // Scale in, alpha in, and slide in from bottom new items
                            mRecyclerView.setAdapter(new SlideInBottomAnimationAdapter(
                                    new ScaleInAnimationAdapter(new AlphaInAnimationAdapter(adapter))));
                        } else {
                            // Add our results to what we already have
                            mMovies.addAll(parseObjects);
                            mRecyclerView.getAdapter().notifyDataSetChanged();
                        }
                    } else {
                        Utils.showError(getActivity(), TAG, "Error querying movies", e, e.getLocalizedMessage());
                    }
                }
            });
        }

        /**
         * Used with EventBus
         */

        public void onEvent(MovieResponse response) {
            if (response.getResults() != null) {
                // Fill our search ListView with search results
                mSearchedMovies = response.getResults();
                SearchMovieAdapter adapter = new SearchMovieAdapter(getActivity(), mSearchedMovies);
                mSearchListView.setAdapter(adapter);
            }
        }

        public void onEvent(RetrofitError error) {
            Toast.makeText(getActivity(), error.getLocalizedMessage(), Toast.LENGTH_SHORT).show();
        }

        public class MovieAdapter extends RecyclerView.Adapter<MovieAdapter.ViewHolder> {
            private List<ParseObject> movies;

            public MovieAdapter(List<ParseObject> movies) {
                this.movies = movies;
            }

            @Override
            public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
                View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.list_movie, viewGroup, false);
                // If in landscape (tablet or phone), alter the size of the view to adjust
                // proportionally to the movie poster (27:40)
                if (!Utils.isPortrait(getActivity())) {
                    Point size = Utils.getScreenDimensions(getActivity());
                    // Get the adjusted height of the screen (screen height - action bar height)
                    // (Had to multiply action bar height by 2 for some reason to get the correct height)
                    size.y -= (Utils.getActionBarHeight(getActivity()) * 2);
                    // And get the width based on that height
                    int newWidth = 27 * size.y / 40;
                    // Set these values to each list item
                    RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(newWidth, size.y);
                    v.setLayoutParams(lp);
                } else if (Utils.isTablet(getActivity())) {
                    // Else if a tablet in portrait, do the same thing, but adjust to the width of the
                    // view's parent width (should be half the screen width since it's laid out in
                    // 2 columns
                    Point size = Utils.getScreenDimensions(getActivity());
                    int newHeight = (size.x / 2) * 40 / 27;
                    RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(v.getWidth(), newHeight);
                    v.setLayoutParams(lp);
                }
                return new ViewHolder(v);
            }

            @TargetApi(21)
            @Override
            public void onBindViewHolder(ViewHolder holder, int position) {
                ParseObject movie = movies.get(position);

                // Reset background to black when scrolling down
                holder.itemView.setBackgroundColor(Color.BLACK);
                // And set the button bgs depending on whether user voted or not for this movie
                boolean hasRated = mMovieRatings.containsKey(movie.getNumber("movie_id").intValue());
                if (hasRated) {
                    MovieRating movieRating = mMovieRatings.get(movie.getNumber("movie_id").intValue());
                    if (movieRating.isAwkward()) {
                        holder.yesAwkward.setBackgroundResource(R.drawable.red_button_bg);
                        holder.noAwkward.setBackgroundResource(R.drawable.transparent_button_bg);
                    } else {
                        holder.yesAwkward.setBackgroundResource(R.drawable.transparent_button_bg);
                        holder.noAwkward.setBackgroundResource(R.drawable.green_button_bg);
                    }
                } else {
                    holder.yesAwkward.setBackgroundResource(R.drawable.transparent_button_bg);
                    holder.noAwkward.setBackgroundResource(R.drawable.transparent_button_bg);
                }

                holder.title.setText(movie.getString("title"));

                // Set awkward rating based on votes
                int percent = movie.getInt("awkwardness");
                if (percent == -1)
                    holder.rating.setText("No rating");
                else
                    holder.rating.setText(percent + "% awkward");

                if (movie.getString("poster_path") != null) {
                    // Get movie poster and Palette color
                    // the background to be colored on phones is the entire bg of the view
                    // the background to be colored on tablets or phones in landscape
                    // is the bg that is under the text
                    final View background = (!Utils.isTablet(getActivity()) && Utils.isPortrait(getActivity()))
                            ? holder.itemView
                            : holder.bottomLayout;
                    final ImageView iv = holder.poster;
                    Uri uri = Uri.parse("https://image.tmdb.org/t/p/w300" + movie.getString("poster_path")
                            + "?api_key=" + NetworkHelper.getInstance(getActivity()).getApiKey());
                    Picasso.with(getActivity()).load(uri).into(holder.poster, new Callback() {
                        @Override
                        public void onSuccess() {
                            if (iv != null) {
                                Palette.generateAsync(Utils.getImageViewBitmap(iv),
                                        new Palette.PaletteAsyncListener() {
                                            @Override
                                            public void onGenerated(Palette p) {
                                                int color = p.getDarkMutedColor(
                                                        p.getMutedColor(p.getDarkVibrantColor(0xff000000)));
                                                if (getActivity() != null && (!Utils.isPortrait(getActivity())
                                                        || Utils.isTablet(getActivity()))) {
                                                    // Have the alpha be 0.7 in landscape (phones)
                                                    // Or 0.7 for tablets in general
                                                    // 0.7 alpha is 179/255
                                                    int newColor = Color.argb(179, Color.red(color),
                                                            Color.green(color), Color.blue(color));
                                                    Utils.animateToColor(background, newColor);
                                                } else {
                                                    Utils.animateToColor(background, color);
                                                }
                                            }
                                        });
                            }
                        }

                        @Override
                        public void onError() {

                        }
                    });
                }

                // To keep track of which movie we're referring to when we press the yes/no buttons
                holder.yesAwkward.setTag(position);
                holder.noAwkward.setTag(position);
                holder.yesAwkward.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        int position = (Integer) v.getTag();
                        ParseObject movie = mMovies.get(position);
                        VoteHelper.vote(getActivity(), movie, true, mMovieRatings);
                        // Finally, update our buttons
                        mRecyclerView.getAdapter().notifyItemChanged(position);
                    }
                });
                holder.noAwkward.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        int position = (Integer) v.getTag();
                        ParseObject movie = mMovies.get(position);
                        VoteHelper.vote(getActivity(), movie, false, mMovieRatings);
                        // Finally, update our buttons
                        mRecyclerView.getAdapter().notifyItemChanged(position);
                    }
                });

                // And a click listener for the entire item itself to bring up a detailed movie page
                holder.itemView.setTag(position);
                holder.itemView.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        int position = (int) v.getTag();
                        mLastPosition = position;
                        ParseObject movie = mMovies.get(position);
                        Intent i = new Intent(getActivity(), MovieActivity.class);
                        i.putExtra(MovieActivity.EXTRA_ID, movie.getNumber("movie_id").intValue());
                        if (Utils.isAtApiLevel(21)) {
                            // Call this version of startActivity to allow the transition animations
                            // to happen
                            getActivity().startActivity(i,
                                    ActivityOptions.makeSceneTransitionAnimation(getActivity()).toBundle());
                        } else {
                            startActivity(i);
                        }
                    }
                });
            }

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

            public class ViewHolder extends RecyclerView.ViewHolder {
                public TextView title, rating;
                public ImageView poster;
                public Button yesAwkward, noAwkward;
                public View bottomLayout;

                public ViewHolder(View v) {
                    super(v);
                    title = (TextView) v.findViewById(R.id.title);
                    rating = (TextView) v.findViewById(R.id.rating);
                    poster = (ImageView) v.findViewById(R.id.poster);
                    yesAwkward = (Button) v.findViewById(R.id.awkwardButton);
                    noAwkward = (Button) v.findViewById(R.id.notAwkwardButton);
                    bottomLayout = v.findViewById(R.id.bottomLayout);
                }
            }
        }

        // Using a different adapter other than MainFragment.MovieAdapter to keep this implementation simple
        // Plus it uses a different layout
        public class SearchMovieAdapter extends ArrayAdapter<Movie> {
            public SearchMovieAdapter(Context c, List<Movie> movies) {
                super(c, 0, movies);
            }

            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                if (convertView == null) {
                    convertView = LayoutInflater.from(getContext()).inflate(R.layout.list_movie_search, parent,
                            false);
                }

                Movie m = getItem(position);

                // Set movie title
                TextView title = (TextView) convertView.findViewById(R.id.title);
                title.setText(m.getTitle());

                // and release date if there is one
                TextView releaseDate = (TextView) convertView.findViewById(R.id.releaseDate);
                releaseDate.setVisibility(View.VISIBLE);
                try {
                    if (m.getReleaseDate() != null && !m.getReleaseDate().isEmpty()) {
                        SimpleDateFormat originalFormat = new SimpleDateFormat("yyyy-MM-dd");
                        Date date = originalFormat.parse(m.getReleaseDate());
                        SimpleDateFormat newFormat = new SimpleDateFormat("MMMM yyyy");
                        releaseDate.setText(newFormat.format(date));
                    } else {
                        releaseDate.setVisibility(View.GONE);
                    }
                } catch (Exception e) {
                    Log.e(TAG, "Error parsing date", e);
                    releaseDate.setVisibility(View.GONE);
                }

                // Set movie poster and Palette color
                final ImageView poster = (ImageView) convertView.findViewById(R.id.poster);
                final View background = convertView;
                Uri uri = Uri.parse("https://image.tmdb.org/t/p/w150" + m.getPosterPath() + "?api_key="
                        + NetworkHelper.getInstance(getContext()).getApiKey());
                Picasso.with(getContext()).load(uri).into(poster, new Callback() {
                    @Override
                    public void onSuccess() {
                        if (poster != null) {
                            Palette.generateAsync(Utils.getImageViewBitmap(poster),
                                    new Palette.PaletteAsyncListener() {
                                        @Override
                                        public void onGenerated(Palette p) {
                                            int color = p.getDarkMutedColor(
                                                    p.getMutedColor(p.getDarkVibrantColor(0xff000000)));
                                            Utils.animateToColor(background, color);
                                        }
                                    });
                        }
                    }

                    @Override
                    public void onError() {

                    }
                });

                return convertView;
            }
        }
    }
}