com.beesham.popularmovies.DetailsFragment.java Source code

Java tutorial

Introduction

Here is the source code for com.beesham.popularmovies.DetailsFragment.java

Source

/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.beesham.popularmovies;

import android.content.ContentValues;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;

import com.beesham.popularmovies.data.MoviesContract;
import com.beesham.popularmovies.data.MoviesContract.MoviesEntry;
import com.beesham.popularmovies.data.MoviesContract.MoviesFavoriteEntry;
import com.squareup.picasso.Picasso;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;

import butterknife.BindView;
import butterknife.ButterKnife;

import static android.R.attr.data;

/**
 * A simple {@link Fragment} subclass.
 * Displays details for the selected movie
 */
public class DetailsFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor> {

    private static final String LOG_TAG = DetailsFragment.class.getSimpleName();

    private Uri mUri;
    private Cursor mCursor;

    static final String DETAIL_URI = "URI";
    private static final int MOVIE_LOADER = 1;
    private static final int MOVIE_FAVORITE_LOADER = 2;

    @BindView(R.id.title_textview)
    TextView titleTextView;
    @BindView(R.id.poster_imageview)
    ImageView posterImageView;
    @BindView(R.id.release_date_textview)
    TextView releaseDateTextView;
    @BindView(R.id.overview_textview)
    TextView overviewTextView;
    @BindView(R.id.rating_textview)
    TextView ratingsTextView;
    @BindView(R.id.favorite_button)
    Button favoriteButton;
    @BindView(R.id.list_trailers)
    ListView trailersListView;
    @BindView(R.id.empty_trailers_textview)
    TextView emptyTrailersTextView;
    @BindView(R.id.list_reviews)
    ListView reviewsListView;
    @BindView(R.id.empty_reviews_textview)
    TextView emptyReviewsTextView;

    private String mReviewJSONStr;
    private String mTrailersJSONStr;
    private ArrayList mTrailerList;
    private TrailersAdapter mTrailersAdapter;
    private ReviewAdapter mReviewAdapter;
    private ArrayList mReviewsList;

    /**
     * This object holds data to be used in the trailers listview
     */
    class Trailer {
        String trailerName;
        String trailerKey;

        public Trailer(String trailerName, String trailerKey) {
            this.trailerName = trailerName;
            this.trailerKey = trailerKey;
        }

        public String getTrailerName() {
            return trailerName;
        }

        public String getTrailerKey() {
            return trailerKey;
        }
    }

    /**
     * This object holds data to be used in the reviews listview
     */
    class Reviews {
        String author;
        String url;

        public Reviews(String author, String url) {
            this.author = author;
            this.url = url;
        }

        public String getAuthor() {
            return author;
        }

        public String getUrl() {
            return url;
        }
    }

    public interface Callback {
        void onItemSelected(Uri title);
    }

    public DetailsFragment() {
        // Required empty public constructor
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_details_view, container, false);
        ButterKnife.bind(this, rootView);

        mTrailerList = new ArrayList();
        mReviewsList = new ArrayList();

        mReviewAdapter = new ReviewAdapter(getActivity(), mReviewsList);
        reviewsListView.setAdapter(mReviewAdapter);
        reviewsListView.setEmptyView(emptyReviewsTextView);

        mTrailersAdapter = new TrailersAdapter(getActivity(), mTrailerList);
        trailersListView.setAdapter(mTrailersAdapter);
        trailersListView.setEmptyView(emptyTrailersTextView);
        trailersListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                Intent intent = new Intent();
                intent.setAction(Intent.ACTION_VIEW);

                String movieBaseYoutubeUrl = getString(R.string.movies_base_youtube_url,
                        ((Trailer) mTrailerList.get(i)).getTrailerKey());

                intent.setData(Uri.parse(movieBaseYoutubeUrl));
                if (intent.resolveActivity(getActivity().getPackageManager()) != null) {
                    startActivity(intent);
                }
            }
        });

        favoriteButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (checkForFavorite()) {
                    removeFavorite();
                    favoriteButton.setText(R.string.mark_favorite);
                } else {
                    insertFavoriteMovie();
                    favoriteButton.setText(R.string.mark_unfavorite);
                }
            }
        });

        Bundle args = getArguments();
        if (args != null) {
            mUri = args.getParcelable(DetailsFragment.DETAIL_URI);
        }

        if (savedInstanceState != null && args.containsKey(DetailsFragment.DETAIL_URI)) {
            mUri = args.getParcelable(DetailsFragment.DETAIL_URI);
        }

        return rootView;
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        if (mUri != null) {
            outState.putParcelable(DetailsFragment.DETAIL_URI, mUri);
        }
        super.onSaveInstanceState(outState);
    }

    /**
     * Checks if the movie is already favored
     * @return boolean true or false
     */
    private boolean checkForFavorite() {
        Cursor c = getActivity().getContentResolver().query(MoviesContract.MoviesFavoriteEntry.CONTENT_URI,
                new String[] { MoviesContract.MoviesFavoriteEntry.COLUMN_MOVIE_ID },
                MoviesContract.MoviesFavoriteEntry.COLUMN_MOVIE_ID + "=?",
                new String[] {
                        mCursor.getString(mCursor.getColumnIndex(MoviesContract.MoviesEntry.COLUMN_MOVIE_ID)) },
                null);

        if (c.moveToFirst()) {
            c.close();
            return true;
        } else {
            return false;
        }
    }

    /**
     * Inserts the movie into the database
     */
    private void insertFavoriteMovie() {
        String title = mCursor.getString(mCursor.getColumnIndex(MoviesContract.MoviesEntry.COLUMN_MOVIE_TITLE));
        String id = mCursor.getString(mCursor.getColumnIndex(MoviesContract.MoviesEntry.COLUMN_MOVIE_ID));
        String overview = mCursor
                .getString(mCursor.getColumnIndex(MoviesContract.MoviesEntry.COLUMN_MOVIE_SYNOPSIS));
        String posterPath = mCursor
                .getString(mCursor.getColumnIndex(MoviesContract.MoviesEntry.COLUMN_MOVIE_POSTER));
        String rating = mCursor
                .getString(mCursor.getColumnIndex(MoviesContract.MoviesEntry.COLUMN_MOVIE_USER_RATING));
        String release_date = mCursor
                .getString(mCursor.getColumnIndex(MoviesContract.MoviesEntry.COLUMN_MOVIE_RELEASE_DATE));
        String trailers = mCursor
                .getString(mCursor.getColumnIndex(MoviesContract.MoviesEntry.COLUMN_MOVIE_TRAILERS));
        String reviews = mCursor.getString(mCursor.getColumnIndex(MoviesContract.MoviesEntry.COLUMN_MOVIE_REVIEWS));

        ContentValues movieValues = new ContentValues();

        movieValues.put(MoviesContract.MoviesEntry.COLUMN_MOVIE_ID, id);
        movieValues.put(MoviesContract.MoviesEntry.COLUMN_MOVIE_TITLE, title);
        movieValues.put(MoviesContract.MoviesEntry.COLUMN_MOVIE_SYNOPSIS, overview);
        movieValues.put(MoviesContract.MoviesEntry.COLUMN_MOVIE_POSTER, posterPath);
        movieValues.put(MoviesContract.MoviesEntry.COLUMN_MOVIE_USER_RATING, rating);
        movieValues.put(MoviesContract.MoviesEntry.COLUMN_MOVIE_RELEASE_DATE, release_date);
        movieValues.put(MoviesContract.MoviesEntry.COLUMN_MOVIE_TRAILERS, trailers);
        movieValues.put(MoviesContract.MoviesEntry.COLUMN_MOVIE_REVIEWS, reviews);

        getActivity().getContentResolver().insert(MoviesContract.MoviesFavoriteEntry.CONTENT_URI, movieValues);
    }

    /**
     * Removes the movies from the favorites
     */
    private void removeFavorite() {
        String selection = MoviesContract.MoviesFavoriteEntry.COLUMN_MOVIE_ID + "=?";
        String[] selectionArgs = new String[] {
                mCursor.getString(mCursor.getColumnIndex(MoviesContract.MoviesEntry.COLUMN_MOVIE_ID)) };
        getActivity().getContentResolver().delete(MoviesContract.MoviesFavoriteEntry.CONTENT_URI, selection,
                selectionArgs);
    }

    /**
     * Parses the trailer information needed to create
     * a Trailer object. This object will then be used
     * in the trailers listview
     */
    private void parseTrailers() {
        try {
            JSONObject trailersJSONObject = new JSONObject(mTrailersJSONStr);
            JSONArray trailersListJSON = trailersJSONObject.getJSONArray("results");
            for (int i = 0; i < trailersListJSON.length(); i++) {
                JSONObject trailerJSON = trailersListJSON.getJSONObject(i);
                mTrailerList.add(new Trailer(trailerJSON.getString("name"), trailerJSON.getString("key")));
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
        mTrailersAdapter.notifyDataSetChanged();
    }

    /**
    * Parses the author and the review url from the JSON object based on the position
    * in the listview
    */
    private void parseReview() {
        try {
            if (mReviewJSONStr != null) {
                JSONObject reviewJSONObject = new JSONObject(mReviewJSONStr);
                JSONArray reviewsListJSON = reviewJSONObject.getJSONArray("results");
                for (int i = 0; i < reviewsListJSON.length(); i++) {
                    JSONObject trailerJSON = reviewsListJSON.getJSONObject(i);
                    mReviewsList.add(new Reviews(trailerJSON.getString("author"), trailerJSON.getString("url")));
                }
            }

        } catch (JSONException e) {
            e.printStackTrace();
        }
        mReviewAdapter.notifyDataSetChanged();
    }

    /**
     * Parses the year out of the release date
     * e.g 2016 out of 2016/01/09
     * @param releaseDate
     * @return String of the year
     */
    private String parseReleaseYear(String releaseDate) {
        String releaseYear = releaseDate.substring(0, 4);
        return releaseYear;
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
        String sort_by = prefs.getString(getContext().getString(R.string.pref_sort_key),
                getContext().getString(R.string.pref_sort_default));

        if (sort_by.equals(getString(R.string.pref_sort_favorite))) {
            getLoaderManager().initLoader(MOVIE_FAVORITE_LOADER, null, this);
        } else {
            getLoaderManager().initLoader(MOVIE_LOADER, null, this);
        }
        super.onActivityCreated(savedInstanceState);
    }

    @Override
    public Loader<Cursor> onCreateLoader(int id, Bundle args) {

        switch (id) {
        case 1:
            return loadFromMovieEntry();

        case 2:
            return loadFromMovieFavoriteEntry();
        }
        return null;
    }

    private CursorLoader loadFromMovieEntry() {
        String[] projection = new String[] { MoviesEntry._ID, MoviesEntry.COLUMN_MOVIE_ID,
                MoviesEntry.COLUMN_MOVIE_TITLE, MoviesEntry.COLUMN_MOVIE_SYNOPSIS, MoviesEntry.COLUMN_MOVIE_POSTER,
                MoviesEntry.COLUMN_MOVIE_RELEASE_DATE, MoviesEntry.COLUMN_MOVIE_USER_RATING,
                MoviesEntry.COLUMN_MOVIE_TRAILERS, MoviesEntry.COLUMN_MOVIE_REVIEWS };

        if (mUri != null) {
            String selection = MoviesEntry.COLUMN_MOVIE_TITLE + "=?";
            String[] selectionArgs = { mUri.getPathSegments().get(1) };

            return new CursorLoader(getActivity(), MoviesEntry.CONTENT_URI, projection, selection, selectionArgs,
                    null);
        }
        return null;
    }

    private CursorLoader loadFromMovieFavoriteEntry() {
        String[] projection = new String[] { MoviesFavoriteEntry._ID, MoviesFavoriteEntry.COLUMN_MOVIE_ID,
                MoviesFavoriteEntry.COLUMN_MOVIE_TITLE, MoviesFavoriteEntry.COLUMN_MOVIE_SYNOPSIS,
                MoviesFavoriteEntry.COLUMN_MOVIE_POSTER, MoviesFavoriteEntry.COLUMN_MOVIE_RELEASE_DATE,
                MoviesFavoriteEntry.COLUMN_MOVIE_USER_RATING, MoviesFavoriteEntry.COLUMN_MOVIE_TRAILERS,
                MoviesFavoriteEntry.COLUMN_MOVIE_REVIEWS };

        if (mUri != null) {
            String selection = MoviesFavoriteEntry.COLUMN_MOVIE_TITLE + "=?";
            String[] selectionArgs = { mUri.getPathSegments().get(1) };

            return new CursorLoader(getActivity(), MoviesFavoriteEntry.CONTENT_URI, projection, selection,
                    selectionArgs, null);
        }
        return null;
    }

    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
        if (!data.moveToFirst()) {
            return;
        }

        getActivity().findViewById(R.id.details_linear_layout).setVisibility(View.VISIBLE);

        switch (loader.getId()) {
        case 1:
            titleTextView
                    .setText(data.getString(data.getColumnIndex(MoviesContract.MoviesEntry.COLUMN_MOVIE_TITLE)));
            Picasso.with(getContext())
                    .load(data.getString(data.getColumnIndex(MoviesContract.MoviesEntry.COLUMN_MOVIE_POSTER)))
                    .into(posterImageView);
            overviewTextView
                    .setText(data.getString(data.getColumnIndex(MoviesContract.MoviesEntry.COLUMN_MOVIE_SYNOPSIS)));
            ratingsTextView.setText(getString(R.string.rating,
                    data.getInt(data.getColumnIndex(MoviesContract.MoviesEntry.COLUMN_MOVIE_USER_RATING))));
            releaseDateTextView.setText(parseReleaseYear(data
                    .getString(data.getColumnIndex(MoviesContract.MoviesFavoriteEntry.COLUMN_MOVIE_RELEASE_DATE))));
            mTrailersJSONStr = data
                    .getString(data.getColumnIndex(MoviesContract.MoviesEntry.COLUMN_MOVIE_TRAILERS));
            mReviewJSONStr = data.getString(data.getColumnIndex(MoviesContract.MoviesEntry.COLUMN_MOVIE_REVIEWS));
            break;

        case 2:
            titleTextView.setText(
                    data.getString(data.getColumnIndex(MoviesContract.MoviesFavoriteEntry.COLUMN_MOVIE_TITLE)));
            Picasso.with(getContext())
                    .load(data
                            .getString(data.getColumnIndex(MoviesContract.MoviesFavoriteEntry.COLUMN_MOVIE_POSTER)))
                    .into(posterImageView);
            overviewTextView.setText(
                    data.getString(data.getColumnIndex(MoviesContract.MoviesFavoriteEntry.COLUMN_MOVIE_SYNOPSIS)));
            ratingsTextView.setText(getString(R.string.rating,
                    data.getInt(data.getColumnIndex(MoviesContract.MoviesFavoriteEntry.COLUMN_MOVIE_USER_RATING))));
            releaseDateTextView.setText(parseReleaseYear(data
                    .getString(data.getColumnIndex(MoviesContract.MoviesFavoriteEntry.COLUMN_MOVIE_RELEASE_DATE))));
            mTrailersJSONStr = data
                    .getString(data.getColumnIndex(MoviesContract.MoviesFavoriteEntry.COLUMN_MOVIE_TRAILERS));
            mReviewJSONStr = data
                    .getString(data.getColumnIndex(MoviesContract.MoviesFavoriteEntry.COLUMN_MOVIE_REVIEWS));
            break;
        }

        //Clear the lists of old data if any
        mTrailerList.clear();
        mReviewsList.clear();

        parseTrailers();
        parseReview();
        mCursor = data;

        //Check if the movie is favorite so appropriate
        // button state can be placed
        if (checkForFavorite()) {
            favoriteButton.setText(R.string.mark_unfavorite);
        }
    }

    @Override
    public void onLoaderReset(Loader<Cursor> loader) {
        mTrailerList.clear();
        mReviewsList.clear();

        titleTextView.setText(null);
        overviewTextView.setText(null);
        ratingsTextView.setText(null);
        releaseDateTextView.setText(null);
    }

}