Java tutorial
/* * 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.mycompany.popularmovies.DetailActivity; import android.content.ContentResolver; import android.content.ContentValues; import android.content.Intent; import android.database.Cursor; import android.graphics.Color; import android.graphics.PorterDuff; import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentActivity; import android.support.v4.app.LoaderManager; import android.support.v4.content.CursorLoader; import android.support.v4.content.Loader; import android.support.v4.view.MenuItemCompat; import android.support.v7.widget.ShareActionProvider; 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.widget.ImageView; import android.widget.LinearLayout; import android.widget.RatingBar; import android.widget.RelativeLayout; import android.widget.ScrollView; import android.widget.TextView; import com.mycompany.popularmovies.MainActivity.MainFragment; import com.mycompany.popularmovies.MainActivity.MovieAdapter; import com.mycompany.popularmovies.R; import com.mycompany.popularmovies.data.FetchMoviesTask; import com.mycompany.popularmovies.data.MovieContract; import com.squareup.picasso.Picasso; import java.util.HashMap; /** * A placeholder fragment containing a simple view. */ public class DetailFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor>, View.OnClickListener { private static final String LOG_TAG = DetailFragment.class.getSimpleName(); private static final String[] COLUMNS_TO_RETRIEVE_GENERAL_INFO = new String[] { MovieContract.MovieTable.COLUMN_TITLE, MovieContract.MovieTable.COLUMN_RELEASE_DATE, MovieContract.MovieTable.COLUMN_SYNOPSIS, MovieContract.MovieTable.COLUMN_VOTE_AVERAGE, MovieContract.MovieTable.COLUMN_POPULARITY, MovieContract.MovieTable.COLUMN_POSTER_PATH, MovieContract.MovieTable.COLUMN_FAVORITED }; private static final String[] COLUMNS_TO_RETRIEVE_TRAILERS = { MovieContract.TrailersTable._ID, MovieContract.TrailersTable.COLUMN_SITE, MovieContract.TrailersTable.COLUMN_KEY, MovieContract.TrailersTable.COLUMN_NAME, MovieContract.TrailersTable.COLUMN_LANGUAGE_CODE }; private static final String[] COLUMNS_TO_RETRIEVE_REVIEWS = { MovieContract.TrailersTable._ID, MovieContract.ReviewsTable.COLUMN_AUTHOR, MovieContract.ReviewsTable.COLUMN_REVIEW_TEXT }; private static final int LOADER_ID_GENERAL_INFO = 0; private static final int LOADER_ID_TRAILERS = 1; private static final int LOADER_ID_REVIEWS = 2; private static final int TAG_REVIEW_COLLAPSED = 0; private static final int TAG_REVIEW_EXPANDED = 1; public static final int REVIEW_MAXLINES = 3; private TextView mTitleTextView; private TextView mSynopsisTextView; private RatingBar mRatingBar; private ImageView mPosterImageView; private int mMovieId; private static final String SHARE_INTRODUCTION = "Hey, check out this movie:"; private static final String SHARE_HASHTAG = "#PopularMoviesApp"; private String mShareText; private CursorLoader mGeneralInfoLoader; private CursorLoader mTrailerLoader; private CursorLoader mReviewLoader; private ShareActionProvider mShareActionProvider; private FragmentActivity mActivity; private ImageView mHeartImageView; private LinearLayout mTrailerList; private LinearLayout mReviewList; private TextView mReleaseYearTextView; private int mTheMovieDbId; private View mRootView; private TextView mTrailerListTitle; private TextView mReviewListTitle; private ScrollView mScrollView; public DetailFragment() { } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setHasOptionsMenu(true); } @Override public void onActivityCreated(Bundle savedInstanceState) { getLoaderManager().initLoader(LOADER_ID_GENERAL_INFO, null, this); getLoaderManager().initLoader(LOADER_ID_TRAILERS, null, this); getLoaderManager().initLoader(LOADER_ID_REVIEWS, null, this); super.onActivityCreated(savedInstanceState); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { mActivity = getActivity(); mMovieId = mActivity.getIntent().getIntExtra(MainFragment.INTENT_KEY_CLICKED_MOVIE_ID, -1); mTheMovieDbId = mActivity.getIntent().getIntExtra(MainFragment.INTENT_KEY_CLICKED_THEMOVIEDBID, -1); Log.d(LOG_TAG, String.format("Received movie id = %d, TheMovieDB id = %d, title = %s", mMovieId, mTheMovieDbId, mActivity.getIntent().getStringExtra(MainFragment.INTENT_KEY_CLICKED_TITLE))); mRootView = inflater.inflate(R.layout.detail_fragment, container, false); mScrollView = (ScrollView) mRootView.findViewById(R.id.scroll_view); mPosterImageView = (ImageView) mRootView.findViewById(R.id.poster); mTitleTextView = (TextView) mRootView.findViewById(R.id.title); mHeartImageView = (ImageView) mRootView.findViewById(R.id.favorite); mHeartImageView.setOnClickListener(this); mReleaseYearTextView = (TextView) mRootView.findViewById(R.id.release_year); mRatingBar = (RatingBar) mRootView.findViewById(R.id.rating_bar); mSynopsisTextView = (TextView) mRootView.findViewById(R.id.synopsis); mTrailerListTitle = (TextView) mRootView.findViewById(R.id.trailer_list_title); mTrailerListTitle.setVisibility(View.INVISIBLE); mTrailerList = (LinearLayout) mRootView.findViewById(R.id.trailer_list); mReviewListTitle = (TextView) mRootView.findViewById(R.id.review_list_title); mReviewListTitle.setVisibility(View.INVISIBLE); mReviewList = (LinearLayout) mRootView.findViewById(R.id.review_list); startFetchTrailersAndReviewsTask(mMovieId); return mRootView; } private void startFetchTrailersAndReviewsTask(final int clickedItemRowID) { HashMap<String, Object> paramsHashMap = new HashMap<>(); paramsHashMap.put(FetchMoviesTask.INPUT_PARAM_KEY_ROW_ID, clickedItemRowID); new FetchMoviesTask(getActivity()).execute(paramsHashMap); } @Override public Loader<Cursor> onCreateLoader(int id, Bundle args) { if (id == LOADER_ID_GENERAL_INFO) { mGeneralInfoLoader = new CursorLoader(mActivity, MovieContract.MovieTable.CONTENT_URI, COLUMNS_TO_RETRIEVE_GENERAL_INFO, MovieContract.MovieTable.COLUMN_THEMOVIEDB_ID + " == ?", new String[] { Integer.toString(mTheMovieDbId) }, null); return mGeneralInfoLoader; } else if (id == LOADER_ID_TRAILERS) { mTrailerLoader = new CursorLoader(mActivity, MovieContract.TrailersTable.CONTENT_URI, COLUMNS_TO_RETRIEVE_TRAILERS, MovieContract.TrailersTable.COLUMN_FOREIGN_KEY_MOVIE_ID + " == ?", new String[] { Integer.toString(mMovieId) }, null); return mTrailerLoader; } else if (id == LOADER_ID_REVIEWS) { mReviewLoader = new CursorLoader(mActivity, MovieContract.ReviewsTable.CONTENT_URI, COLUMNS_TO_RETRIEVE_REVIEWS, MovieContract.ReviewsTable.COLUMN_FOREIGN_KEY_MOVIE_ID + " == ?", new String[] { Integer.toString(mMovieId) }, null); return mReviewLoader; } else { throw new UnsupportedOperationException("Unsupported loader ID"); } } @Override public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor cursor) { if (cursorLoader == mGeneralInfoLoader) { if (cursor != null && cursor.moveToFirst()) { int columnIndexPosterPath = cursor.getColumnIndex(MovieContract.MovieTable.COLUMN_POSTER_PATH); String posterPath = MovieAdapter.POSTER_BASE_URL_W185 + cursor.getString(columnIndexPosterPath); Picasso picasso = Picasso.with(getActivity()); picasso.load(posterPath).into(mPosterImageView); int columnIndexTitle = cursor.getColumnIndex(MovieContract.MovieTable.COLUMN_TITLE); String title = cursor.getString(columnIndexTitle); mTitleTextView.setText(title); int columnIndexIsFavorite = cursor.getColumnIndex(MovieContract.MovieTable.COLUMN_FAVORITED); int isFavorite = cursor.getInt(columnIndexIsFavorite); mHeartImageView .setImageResource(isFavorite == 1 ? R.drawable.heart_active : R.drawable.heart_inactive); mHeartImageView.setOnClickListener(this); int columnIndexReleaseDate = cursor.getColumnIndex(MovieContract.MovieTable.COLUMN_RELEASE_DATE); String releaseDateText = cursor.getString(columnIndexReleaseDate); String releaseYearText = releaseDateText.substring(0, Math.min(releaseDateText.length(), 4)); mReleaseYearTextView.setText(releaseYearText); int columnIndexVoteAverage = cursor.getColumnIndex(MovieContract.MovieTable.COLUMN_VOTE_AVERAGE); float vote_average = cursor.getFloat(columnIndexVoteAverage); mRatingBar.setRating(vote_average); int columnIndexSynopsis = cursor.getColumnIndex(MovieContract.MovieTable.COLUMN_SYNOPSIS); mSynopsisTextView.setText(cursor.getString(columnIndexSynopsis)); // If onCreateOptionsMenu has already happened, we need to update the share intent now. if (mShareActionProvider != null) { mShareText = title; mShareActionProvider.setShareIntent(createShareIntent()); } } else { Log.e(LOG_TAG, "Cursor to populate general info was empty or null!"); } } else if (cursorLoader == mTrailerLoader) { if (cursor == null || !cursor.moveToFirst()) { mTrailerListTitle.setVisibility(View.INVISIBLE); } else { mTrailerListTitle.setVisibility(View.VISIBLE); for (cursor.moveToFirst(); cursor.getPosition() < cursor.getCount(); cursor.moveToNext()) { int columnIndexName = cursor.getColumnIndex(MovieContract.TrailersTable.COLUMN_NAME); String trailerName = cursor.getString(columnIndexName); int columnIndexLanguageCode = cursor .getColumnIndex(MovieContract.TrailersTable.COLUMN_LANGUAGE_CODE); String trailerLanguageCode = cursor.getString(columnIndexLanguageCode); String trailer_summary = String.format("%s (%s)", trailerName, trailerLanguageCode.toUpperCase()); int columnIndexSite = cursor.getColumnIndex(MovieContract.TrailersTable.COLUMN_SITE); String site = cursor.getString(columnIndexSite); int columnIndexKey = cursor.getColumnIndex(MovieContract.TrailersTable.COLUMN_KEY); String key = cursor.getString(columnIndexKey); String link = null; if (site.compareTo("YouTube") == 0) { link = "https://www.youtube.com/watch?v=" + key; } else { Log.e(LOG_TAG, "Unsupported site: " + site); } ImageView trailerThumbnail = (ImageView) mActivity.getLayoutInflater() .inflate(R.layout.detail_fragment_trailer_item, null, false); if (site.compareTo("YouTube") == 0) { Picasso picasso = Picasso.with(mActivity); String youtubeThumbnailPath = String.format("http://img.youtube.com/vi/%s/mqdefault.jpg", key); picasso.load(youtubeThumbnailPath).into(trailerThumbnail); trailerThumbnail.setTag(link); trailerThumbnail.setOnClickListener(this); } mTrailerList.addView(trailerThumbnail); } } } else if (cursorLoader == mReviewLoader) { if (cursor == null || !cursor.moveToFirst()) { mReviewListTitle.setVisibility(View.INVISIBLE); } else { mReviewListTitle.setVisibility(View.VISIBLE); String colors[] = { "#00BFFF", "#00CED1", "#FF8C00", "#00FA9A", "#9400D3" }; for (cursor.moveToFirst(); cursor.getPosition() < cursor.getCount(); cursor.moveToNext()) { int columnIndexAuthor = cursor.getColumnIndex(MovieContract.ReviewsTable.COLUMN_AUTHOR); String author = cursor.getString(columnIndexAuthor); String authorAbbreviation = author != null && author.length() >= 1 ? author.substring(0, 1) : "?"; int columnIndexReviewText = cursor .getColumnIndex(MovieContract.ReviewsTable.COLUMN_REVIEW_TEXT); String reviewText = cursor.getString(columnIndexReviewText); RelativeLayout review = (RelativeLayout) mActivity.getLayoutInflater() .inflate(R.layout.detail_fragment_review_item, null, false); review.setOnClickListener(this); review.setTag(TAG_REVIEW_COLLAPSED); TextView authorIcon = (TextView) review.findViewById(R.id.author_icon); authorIcon.setText(authorAbbreviation); int color = Color.parseColor(colors[cursor.getPosition() % colors.length]); authorIcon.getBackground().setColorFilter(color, PorterDuff.Mode.MULTIPLY); TextView authorFullName = (TextView) review.findViewById(R.id.author_full_name); authorFullName.setText(author); TextView reviewTextView = (TextView) review.findViewById(R.id.review_text); reviewTextView.setText(reviewText); mReviewList.addView(review); } } } } @Override public void onLoaderReset(Loader<Cursor> cursorLoader) { } @Override public void onClick(View v) { if (v.getId() == R.id.favorite) { Uri uri = MovieContract.MovieTable.CONTENT_URI; ContentResolver resolver = mActivity.getContentResolver(); Cursor favoriteStatusCursor = resolver.query(uri, new String[] { MovieContract.MovieTable.COLUMN_FAVORITED }, MovieContract.MovieTable._ID + "== ?", new String[] { Integer.toString(mMovieId) }, null); if (favoriteStatusCursor != null && favoriteStatusCursor.moveToFirst()) { Integer favoriteStatus = favoriteStatusCursor .getInt(favoriteStatusCursor.getColumnIndex(MovieContract.MovieTable.COLUMN_FAVORITED)); Integer flippedFavoriteStatus = favoriteStatus == 0 ? 1 : 0; ContentValues updateFavoriteStatusValues = new ContentValues(); updateFavoriteStatusValues.put(MovieContract.MovieTable.COLUMN_FAVORITED, flippedFavoriteStatus); resolver.update(uri, updateFavoriteStatusValues, MovieContract.MovieTable._ID + " == ?", new String[] { Integer.toString(mMovieId) }); favoriteStatusCursor.close(); } } else if (v.getId() == R.id.trailer_thumbnail) { String link = (String) v.getTag(); startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(link))); } else if (v.getId() == R.id.review) { final RelativeLayout reviewItem = (RelativeLayout) v; final TextView author = (TextView) v.findViewById(R.id.author_full_name); final TextView review = (TextView) v.findViewById(R.id.review_text); if (reviewItem.getTag() == DetailFragment.TAG_REVIEW_COLLAPSED) { author.setVisibility(View.VISIBLE); review.setMaxLines(Integer.MAX_VALUE); new Handler().post(new Runnable() { @Override public void run() { int excess = mReviewList.getTop() + reviewItem.getBottom() - (mScrollView.getScrollY() + mScrollView.getHeight()); if (excess > 0) { if (reviewItem.getHeight() <= mScrollView.getHeight()) { mScrollView.smoothScrollBy(0, excess); } else { mScrollView.smoothScrollTo(0, mReviewList.getTop() + reviewItem.getTop()); } } } }); reviewItem.setTag(DetailFragment.TAG_REVIEW_EXPANDED); } else { author.setVisibility(View.GONE); review.setMaxLines(REVIEW_MAXLINES); reviewItem.setTag(DetailFragment.TAG_REVIEW_COLLAPSED); } } } @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { // Inflate the menu; this adds items to the action bar if it is present. inflater.inflate(R.menu.menu_detailfragment, menu); // Retrieve the share menu item MenuItem menuItem = menu.findItem(R.id.action_share); // Get the provider and hold onto it to set/change the share intent. mShareActionProvider = (ShareActionProvider) MenuItemCompat.getActionProvider(menuItem); // If onLoadFinished happens before this, we can go ahead and set the share intent now. if (mShareText != null) { mShareActionProvider.setShareIntent(createShareIntent()); } } private Intent createShareIntent() { if (mShareText == null) { return null; } else { Intent shareIntent = new Intent(Intent.ACTION_SEND); shareIntent.setType("text/plain"); shareIntent.putExtra(Intent.EXTRA_TEXT, String.format("%s %s %s", SHARE_INTRODUCTION, mShareText, SHARE_HASHTAG)); return shareIntent; } } }