Many changes, including Adding Trailers/Reviews

This commit is contained in:
Aargonian
2016-03-02 07:25:15 -05:00
parent ffc52a7f25
commit 7fa36f7a21
23 changed files with 563 additions and 283 deletions

2
.idea/gradle.xml generated
View File

@@ -6,7 +6,7 @@
<option name="distributionType" value="LOCAL" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleHome" value="$APPLICATION_HOME_DIR$/gradle/gradle-2.8" />
<option name="gradleJvm" value="1.8" />
<option name="gradleJvm" value="1.7" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />

2
.idea/misc.xml generated
View File

@@ -37,7 +37,7 @@
<ConfirmationsSetting value="0" id="Add" />
<ConfirmationsSetting value="0" id="Remove" />
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" default="true" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" default="true" assert-keyword="true" jdk-15="true" project-jdk-name="1.7" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.9 KiB

View File

@@ -1,18 +1,25 @@
package com.example.android.popularmovies;
import android.annotation.SuppressLint;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.widget.ShareActionProvider;
import android.util.Log;
import android.util.TypedValue;
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.TextView;
import com.example.android.popularmovies.data.MovieContract;
@@ -26,23 +33,29 @@ import butterknife.ButterKnife;
public class DetailFragment extends Fragment implements View.OnClickListener
{
private static final String LOG_TAG = DetailFragment.class.getSimpleName();
public DetailFragment() {}
public DetailFragment() {
setHasOptionsMenu(true);
}
@Bind(R.id.rating) TextView rating;
@Bind(R.id.releaseDate) TextView release;
@Bind(R.id.runtime) TextView runtime;
@Bind(R.id.overview) TextView overview;
@Bind(R.id.titleView) TextView title;
@Bind(R.id.posterImage) ImageView poster;
@Bind(R.id.star_icon) ImageView favoriteIcon;
@Bind(R.id.favoriteButton) View favoriteButton;
@Bind(R.id.reviewHeader) TextView reviewHeader;
@Bind(R.id.reviewList) LinearLayout reviews;
@Bind(R.id.trailerList) LinearLayout trailerList;
private ShareActionProvider shareActionProvider;
private MovieInfo movie;
private boolean viewCreated;
private boolean displayTitle = false;
@Override
public void onAttach(Context context)
{
public void onAttach(Context context) {
super.onAttach(context);
Log.d(LOG_TAG, "ATTACHED TO ACTIVITY");
}
@@ -74,12 +87,21 @@ public class DetailFragment extends Fragment implements View.OnClickListener
//Check for MovieID here because, if it returns -1, the fragment was not called in a single
//activity, and is likely being displayed along another fragment
if(intent.getIntExtra("MOVIE_ID", -1) == -1)
if(intent.getLongExtra("MOVIE_ID", -1) == -1)
{
displayTitle = true;
}
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater)
{
inflater.inflate(R.menu.detail_fragment, menu);
MenuItem menuItem = menu.findItem(R.id.action_share);
shareActionProvider =
(ShareActionProvider)MenuItemCompat.getActionProvider(menuItem);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
@@ -145,7 +167,7 @@ public class DetailFragment extends Fragment implements View.OnClickListener
setMovieInfo(MovieUtil.getMovie(getActivity(), id));
}
@SuppressLint("SetTextI18n")
private void setMovieInfo(MovieInfo movie)
{
this.movie = movie;
@@ -154,6 +176,7 @@ public class DetailFragment extends Fragment implements View.OnClickListener
overview.setText(movie.getOverview());
release.setText(movie.getReleaseDate());
rating.setText(movie.getRating() + getString(R.string.out_of_ten));
runtime.setText(movie.getRunTime() + getString(R.string.runtime_unit));
title.setText(movie.getTitle());
if(MovieUtil.isFavorite(getActivity(), movie.getId())) {
@@ -163,17 +186,61 @@ public class DetailFragment extends Fragment implements View.OnClickListener
favoriteIcon.setImageBitmap(BitmapFactory.decodeResource(getResources(),
R.drawable.star_not_favorite));
}
trailerList.removeAllViews();
if(movie.getTrailers() != null && movie.getTrailers().length > 0) {
final String[] trailers = movie.getTrailers();
for(int i = 0; i < trailers.length; i++) {
View view = getLayoutInflater(null).inflate(R.layout.trailer_layout, null);
TextView trailerText = (TextView)view.findViewById(R.id.trailerText);
trailerText.setText("Trailer " + (i+1));
view.setOnClickListener(new TrailerClickListener(trailers[i]));
trailerList.addView(view);
}
setShareMovieTrailerIntent(trailers[0]);
}
reviews.removeAllViews();
if(movie.getReviews() != null && movie.getReviews().length > 0) {
reviewHeader.setVisibility(View.VISIBLE);
for(int i = 0; i < movie.getReviews().length; i++) {
TextView view =
(TextView)getLayoutInflater(null).inflate(R.layout.review_layout, null);
view.setText(movie.getReviews()[i]);
reviews.addView(view);
View divider = new View(getActivity());
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT, 1);
int px = (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 5, getResources().getDisplayMetrics());
params.setMargins(0, px, 0, px);
divider.setLayoutParams(params);
divider.setBackgroundColor(getResources().getColor(R.color.dividerColor));
reviews.addView(divider);
}
}
}
}
private void setShareMovieTrailerIntent(String trailer) {
if(shareActionProvider == null)
return;
Intent shareTrailerIntent = new Intent(Intent.ACTION_SEND);
shareTrailerIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
shareTrailerIntent.setType("text/plain");
shareTrailerIntent.putExtra(Intent.EXTRA_TEXT, trailer);
shareActionProvider.setShareIntent(shareTrailerIntent);
}
@Override
public void onClick(View v) {
if(v == favoriteButton) {
if(movie.id > 0) {
if(MovieUtil.isFavorite(getActivity(), movie.id)) {
setFavorite(movie.id, false);
if(movie.getId() > 0) {
if(MovieUtil.isFavorite(getActivity(), movie.getId())) {
setFavorite(movie.getId(), false);
} else {
setFavorite(movie.id, true);
setFavorite(movie.getId(), true);
}
}
}
@@ -192,4 +259,19 @@ public class DetailFragment extends Fragment implements View.OnClickListener
favorite ? R.drawable.star_favorite : R.drawable.star_not_favorite);
favoriteIcon.setImageBitmap(favIcon);
}
private class TrailerClickListener implements View.OnClickListener {
private final String trailer;
public TrailerClickListener(String trailer) {
this.trailer = trailer;
}
@Override
public void onClick(View v) {
Log.d(LOG_TAG, "SHOWING TRAILER: " + trailer);
Intent trailerIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(trailer));
startActivity(trailerIntent);
}
}
}

View File

@@ -93,7 +93,9 @@ public class DiscoverTask extends AsyncTask<Integer, String, Void>
for(int i = 0; i < results.length(); i++)
{
Long id = results.getJSONObject(i).getLong("id");
//Use the 'FromNet' version of GetMovie so we can update any relevant info as well.
//It'll; also grab the reviews and video links for us.
MovieInfo movie = MovieUtil.getMovieFromNet(mContext, id);
if(movie == null) {
Log.w(LOG_TAG, "NULL MOVIE: " + id);

View File

@@ -12,21 +12,21 @@ public class MovieInfo implements Comparable<MovieInfo>
@SuppressWarnings("unused")
private static final String LOG_TAG = MovieInfo.class.getSimpleName();
public long id;
public String title;
public String overview;
public Bitmap poster;
public String releaseDate;
public String posterPath;
public int runTime;
public int vote_count;
public double rating;
public double popularity;
public String[] genres;
private long id;
private String title;
private String overview;
private Bitmap poster;
private String releaseDate;
private String posterPath;
private int runTime;
private int vote_count;
private double rating;
private double popularity;
private String[] genres;
private String[] trailers;
private String[] reviews;
private MovieInfo()
{
}
private MovieInfo(){}
public static MovieBuilder buildMovie() {
return new MovieBuilder();
@@ -47,7 +47,7 @@ public class MovieInfo implements Comparable<MovieInfo>
}
public boolean isValid() {
return movie.id >= 0 && !(movie.title == null || movie.title.isEmpty());
return movie.getId() >= 0 && !(movie.getTitle() == null || movie.getTitle().isEmpty());
}
public MovieBuilder withId(Long id) {
@@ -110,21 +110,33 @@ public class MovieInfo implements Comparable<MovieInfo>
movie.posterPath = path;
return this;
}
public MovieBuilder withTrailers(String[] trailerList)
{
movie.trailers = trailerList;
return this;
}
public MovieBuilder withReviews(String[] reviews)
{
movie.reviews = reviews;
return this;
}
}
@Override
public int compareTo(@NonNull MovieInfo other)
{
if(this.rating < other.rating) {
if(this.getRating() < other.getRating()) {
return 1;
}
else if(this.rating > other.rating) {
else if(this.getRating() > other.getRating()) {
return -1;
}
else {
if(this.vote_count < other.vote_count) {
if(this.getVoteCount() < other.getVoteCount()) {
return 1;
} else if (this.vote_count > other.vote_count) {
} else if (this.getVoteCount() > other.getVoteCount()) {
return -1;
} else {
return 0;
@@ -134,7 +146,7 @@ public class MovieInfo implements Comparable<MovieInfo>
public void applyPoster(ImageView view)
{
view.setImageBitmap(poster);
view.setImageBitmap(getPoster());
}
public Long getId() { return id; }
@@ -173,6 +185,10 @@ public class MovieInfo implements Comparable<MovieInfo>
return genres;
}
public String[] getReviews() { return reviews; }
public String[] getTrailers() { return trailers; }
public static class MalformedMovieException extends RuntimeException {
public MalformedMovieException(String message) {
super(message);

View File

@@ -37,6 +37,8 @@ public class MovieContract {
public static final String COLUMN_VOTE_CNT = "vote_count";
public static final String COLUMN_RATING = "rating";
public static final String COLUMN_GENRES = "genres";
public static final String COLUMN_TRAILERS = "trailers";
public static final String COLUMN_REVIEWS = "reviews";
public static Uri buildMovieUriWithId(long tmdb_id) {
return ContentUris.withAppendedId(CONTENT_URI, tmdb_id);

View File

@@ -31,13 +31,29 @@ public class MovieDbHelper extends SQLiteOpenHelper {
MovieEntry.COLUMN_FAVORITE + " INTEGER NOT NULL DEFAULT 0," +
MovieEntry.COLUMN_VOTE_CNT + " INTEGER NOT NULL," +
MovieEntry.COLUMN_RATING + " REAL NOT NULL," +
MovieEntry.COLUMN_GENRES + " TEXT NOT NULL" +
MovieEntry.COLUMN_GENRES + " TEXT NOT NULL," +
MovieEntry.COLUMN_REVIEWS + " TEXT," +
MovieEntry.COLUMN_TRAILERS + " TEXT" +
" );";
sqLiteDatabase.execSQL(SQL_CREATE_MOVIES_TABLE);
}
@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion) {
//No upgrade because no public version of the app has been released
//No upgrade because no public version of the app has been released, and no updated db
if(oldVersion < 2) {
final String ADD_FAVORITES = "ALTER TABLE " + MovieEntry.TABLE_NAME + " ADD COLUMN " +
MovieEntry.COLUMN_FAVORITE + " INT NOT NULL DEFAULT 0";
sqLiteDatabase.execSQL(ADD_FAVORITES);
}
if(oldVersion < 3) {
final String ADD_REVIEWS = "ALTER TABLE " + MovieEntry.TABLE_NAME + " ADD COLUMN " +
MovieEntry.COLUMN_REVIEWS + " TEXT";
sqLiteDatabase.execSQL(ADD_REVIEWS);
final String ADD_TRAILERS = "ATLER TABLE " + MovieEntry.TABLE_NAME + " ADD COLUMN " +
MovieEntry.COLUMN_TRAILERS + " TEXT";
sqLiteDatabase.execSQL(ADD_TRAILERS);
}
}
}

View File

@@ -5,6 +5,7 @@ import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Looper;
import android.support.annotation.NonNull;
import android.util.Log;
@@ -41,7 +42,9 @@ public final class MovieUtil
MovieContract.MovieEntry.COLUMN_POPULARITY,
MovieContract.MovieEntry.COLUMN_VOTE_CNT,
MovieContract.MovieEntry.COLUMN_GENRES,
MovieContract.MovieEntry.COLUMN_FAVORITE
MovieContract.MovieEntry.COLUMN_FAVORITE,
MovieContract.MovieEntry.COLUMN_TRAILERS,
MovieContract.MovieEntry.COLUMN_REVIEWS
};
@SuppressWarnings("all") private static final int TITLE = 0;
@@ -54,6 +57,8 @@ public final class MovieUtil
@SuppressWarnings("all") private static final int VOTE_COUNT = 7;
@SuppressWarnings("all") private static final int GENRES = 8;
@SuppressWarnings("all") private static final int FAVORITE = 9;
@SuppressWarnings("all") private static final int TRAILERS = 10;
@SuppressWarnings("all") private static final int REVIEWS = 11;
public static MovieInfo getMovie(@NonNull Context context, Long movieID)
{
@@ -90,7 +95,9 @@ public final class MovieUtil
.withPopularity(cursor.getDouble(POPULARITY))
.withRating(cursor.getDouble(RATING))
.withVoteCount(cursor.getInt(VOTE_COUNT))
.withGenres(parseGenres(cursor.getString(GENRES))).build();
.withGenres(convertStringToArray(cursor.getString(GENRES)))
.withReviews(convertStringToArray(cursor.getString(REVIEWS)))
.withTrailers(convertStringToArray(cursor.getString(TRAILERS))).build();
cursor.close();
return movie;
}
@@ -131,14 +138,20 @@ public final class MovieUtil
*/
public static MovieInfo getMovieFromNet(Context context, Long id)
{
String url = TMDB_URL_BASE+"/movie/"+id +"?api_key="+API_KEY;
String movieJSON = NetworkUtil.getURL(url);
if(movieJSON == null || movieJSON.isEmpty()) {
Log.w(LOG_TAG, "Unable to fetch movie from network! TMDB ID: " + id);
return null;
}
Uri movieURI = Uri.parse(TMDB_URL_BASE).buildUpon()
.appendPath("movie")
.appendPath(Long.toString(id))
.appendQueryParameter("api_key", API_KEY)
.appendQueryParameter("append_to_response", "reviews,videos").build();
String movieJSON = null;
try
{
movieJSON = NetworkUtil.getURL(movieURI.toString());
if(movieJSON == null || movieJSON.isEmpty()) {
Log.w(LOG_TAG, "Unable to fetch movie from network! TMDB ID: " + id);
return null;
}
JSONObject movieObject = new JSONObject(movieJSON);
JSONArray genreList = movieObject.getJSONArray("genres");
String[] genres = new String[genreList.length()];
@@ -149,6 +162,8 @@ public final class MovieUtil
String posterPath = movieObject.getString("poster_path");
String releaseDate = movieObject.getString("release_date");
System.out.println("MOVIE JSON: " + movieJSON);
//Individual Tries for Malformed Movies
int runTime = 0;
int votes = 0;
@@ -176,6 +191,41 @@ public final class MovieUtil
Log.e(LOG_TAG, "Unable To Get MovieInfo Poster: " + ex.getMessage(), ex);
}
//GetReviews
String[] reviews = null;
JSONObject reviewObject = movieObject.getJSONObject("reviews");
try {
JSONArray reviewList = reviewObject.getJSONArray("results");
if (reviewList.length() > 0) {
reviews = new String[reviewList.length() > 3 ? 3 : reviewList.length()];
for (int i = 0; i < reviewList.length() && i < 3; i++) {
reviews[i] = reviewList.getJSONObject(i).getString("content");
}
}
} catch (JSONException ex) {
Log.e(LOG_TAG, "Error Retrieving Reviews: " + ex.getMessage(), ex);
Log.e(LOG_TAG, "REVIEW JSON: " + reviewObject.toString());
}
//Get Trailers
final String YOUTUBE_BASE_VIDEO_URL = "https://www.youtube.com/watch?v=";
String[] trailers = null;
JSONObject trailerObject = movieObject.getJSONObject("videos");
try {
JSONArray trailerList = trailerObject.getJSONArray("results");
if (trailerList.length() > 0) {
trailers = new String[trailerList.length() > 3 ? 3 : trailerList.length()];
for (int i = 0; i < trailerList.length() && i < 3; i++) {
trailers[i] =
YOUTUBE_BASE_VIDEO_URL + trailerList.getJSONObject(i).getString("key");
}
}
} catch (JSONException ex) {
Log.e(LOG_TAG, "ERROR GETTING TRAILERS: " + ex.getMessage(), ex);
Log.e(LOG_TAG, "TRAILER JSON: " + trailerObject.toString());
}
MovieInfo info = MovieInfo.buildMovie().withId(id)
.withTitle(title)
.withGenres(genres)
@@ -186,7 +236,9 @@ public final class MovieUtil
.withRating(vote)
.withVoteCount(votes)
.withPopularity(popularity)
.withPosterPath(imgPath).build();
.withPosterPath(imgPath)
.withReviews(reviews)
.withTrailers(trailers).build();
upsertMovie(context, info); //For caching purposes
return info;
} catch (JSONException ex) {
@@ -196,25 +248,27 @@ public final class MovieUtil
}
}
private static final Character GENRE_DELIMITER = '_';
public static final String STR_SEPARATOR = "__,__";
private static String[] parseGenres(String genres)
{
return genres.split(Character.toString(GENRE_DELIMITER));
}
private static String encodeGenres(String[] genres)
{
public static String convertArrayToString(String[] array){
if(array == null)
return null;
StringBuilder builder = new StringBuilder();
for(int i = 0; i < genres.length; i++)
{
builder.append(genres[i]);
if(i != genres.length-1)
builder.append(GENRE_DELIMITER);
for (int i = 0;i<array.length; i++) {
builder.append(array[i]);
if(i<array.length-1){
builder.append(STR_SEPARATOR);
}
}
return builder.toString();
}
public static String[] convertStringToArray(String str){
if(str == null)
return null;
return str.split(STR_SEPARATOR);
}
private static Bitmap getPoster(Context context, String posterPath) throws IOException
{
if(context == null || posterPath == null || posterPath.isEmpty())
@@ -243,7 +297,11 @@ public final class MovieUtil
values.put(MovieContract.MovieEntry.COLUMN_RUNTIME, movie.getRunTime());
values.put(MovieContract.MovieEntry.COLUMN_TITLE, movie.getTitle());
values.put(MovieContract.MovieEntry.COLUMN_VOTE_CNT, movie.getVoteCount());
values.put(MovieContract.MovieEntry.COLUMN_GENRES, encodeGenres(movie.getGenres()));
values.put(MovieContract.MovieEntry.COLUMN_GENRES, convertArrayToString(movie.getGenres()));
values.put(MovieContract.MovieEntry.COLUMN_REVIEWS,
convertArrayToString(movie.getReviews()));
values.put(MovieContract.MovieEntry.COLUMN_TRAILERS,
convertArrayToString(movie.getTrailers()));
if(cursor.getCount() == 0 || !cursor.moveToFirst()) {
storeMovie(context, values);

View File

@@ -18,7 +18,6 @@ import java.net.InetSocketAddress;
import java.net.MalformedURLException;
import java.net.Socket;
import java.net.URL;
import java.util.ArrayList;
/**
* Created by Aaron Helton on 1/30/2016
@@ -26,56 +25,13 @@ import java.util.ArrayList;
public final class NetworkUtil
{
private static final String LOG_TAG = NetworkUtil.class.getSimpleName();
private static final ArrayList<Long> requestTimes = new ArrayList<>();
private static final ArrayList<Long> imgRequestTimes = new ArrayList<>();
public static String getURL(String urlString) {
long nano = System.nanoTime();
String res = getUrlImpl(urlString);
//Statistics
long time = (System.nanoTime()-nano)/1000000;
requestTimes.add(time);
long avg = 0;
long min = 10000;
long max = -1;
Log.d(LOG_TAG, "REQUEST: " + time + "ms");
for(Long num : requestTimes)
{
if(num < min) min = num;
if(num > max) max = num;
avg += num;
}
Log.d(LOG_TAG, "AVERAGE TIME: " + ((double)avg/requestTimes.size()) + "ms");
Log.d(LOG_TAG, "MAX TIME: " + max + "ms");
Log.d(LOG_TAG, "MIN TIME: " + min + "ms");
return res;
return getUrlImpl(urlString);
}
public static Bitmap getImage(String url, Context context, Bitmap defImg) {
long nano = System.nanoTime();
//Tests on target device show that the straight HTTPUrlConnection version actually performs
//faster on average than Picasso, and images being stored as an ImageView later means we
//don't quite benefit as much from the image cache to make it worth using.
Bitmap bm = defImageImpl(url, context, defImg);
long time = (System.nanoTime()-nano)/1000000;
imgRequestTimes.add(time);
long avg = 0;
long min = 10000;
long max = -1;
Log.d(LOG_TAG, "IMAGE REQUEST: " + time + "ms");
for(Long num : imgRequestTimes)
{
if(num < min) min = num;
if(num > max) max = num;
avg += num;
}
Log.d(LOG_TAG, "AVERAGE TIME: " + ((double)avg/imgRequestTimes.size()) + "ms");
Log.d(LOG_TAG, "MAX TIME: " + max + "ms");
Log.d(LOG_TAG, "MIN TIME: " + min + "ms");
return bm;
return defImageImpl(url, context, defImg);
}
private static Bitmap defImageImpl(String url, Context context, Bitmap defImg)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 822 B

View File

@@ -25,50 +25,78 @@
android:layout_height="match_parent"
android:background="@color/white"
android:clipToPadding="false">
<RelativeLayout
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RelativeLayout
android:id="@+id/detailRelative"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
style="@style/Poster_Image_Details"
android:id="@+id/posterImage"
android:layout_width="wrap_content"
android:src="@mipmap/ic_launcher" />
<include layout="@layout/detail_text_fields"
android:id="@+id/text_fields"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@id/posterImage"
android:layout_toRightOf="@id/posterImage"
android:layout_toEndOf="@id/posterImage"
android:layout_marginTop="20dp"
android:layout_marginRight="10dp"
android:layout_marginEnd="10dp" />
<include layout="@layout/favorite_button"
android:id="@+id/favoriteButton"
android:layout_width="1px"
android:layout_height="wrap_content"
android:layout_alignLeft="@id/posterImage"
android:layout_alignStart="@id/posterImage"
android:layout_alignRight="@id/posterImage"
android:layout_alignEnd="@id/posterImage"
android:layout_below="@id/posterImage"
android:layout_marginBottom="5dp"/>
<TextView
android:id="@+id/overview"
<ImageView
style="@style/Poster_Image_Details"
android:id="@+id/posterImage"
android:layout_width="wrap_content"
android:src="@mipmap/ic_launcher" />
<include layout="@layout/detail_text_fields"
android:id="@+id/text_fields"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@id/posterImage"
android:layout_toRightOf="@id/posterImage"
android:layout_toEndOf="@id/posterImage"
android:layout_marginTop="20dp"
android:layout_marginRight="10dp"
android:layout_marginEnd="10dp" />
<include layout="@layout/favorite_button"
android:id="@+id/favoriteButton"
android:layout_width="1px"
android:layout_height="wrap_content"
android:layout_alignLeft="@id/posterImage"
android:layout_alignStart="@id/posterImage"
android:layout_alignRight="@id/posterImage"
android:layout_alignEnd="@id/posterImage"
android:layout_below="@id/posterImage"
android:layout_marginBottom="5dp"/>
<TextView
android:id="@+id/overview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/text_fields"
android:layout_toRightOf="@id/posterImage"
android:layout_toEndOf="@id/posterImage"
android:layout_marginTop="10dp"
android:layout_marginRight="10dp"
android:layout_marginEnd="10dp"
android:padding="10dp"
android:elevation="4dp"
android:background="@color/colorPrimary"
android:textColor="@color/white"
android:text="In a land long ago and far far away."/>
</RelativeLayout>
<LinearLayout
android:id="@+id/trailerList"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/text_fields"
android:layout_toRightOf="@id/posterImage"
android:layout_toEndOf="@id/posterImage"
android:layout_marginTop="10dp"
android:layout_marginRight="10dp"
android:layout_marginEnd="10dp"
android:padding="10dp"
android:elevation="4dp"
android:background="@color/colorPrimary"
android:textColor="@color/white"
android:text="In a land long ago and far far away."/>
</RelativeLayout>
android:orientation="vertical" />
<LinearLayout
android:id="@+id/reviewList"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:divider="@color/dividerColor"
android:dividerHeight="5dp"
android:orientation="vertical">
<TextView
android:id="@+id/reviewHeader"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:textAlignment="center"
android:textSize="36sp"
android:textColor="@color/primaryText"
android:text="@string/reviews_header"
android:visibility="gone"/>
</LinearLayout>
</LinearLayout>
</ScrollView>
</RelativeLayout>

View File

@@ -25,50 +25,79 @@
android:layout_height="match_parent"
android:background="@color/white"
android:clipToPadding="false">
<RelativeLayout
android:id="@+id/detailRelative"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
style="@style/Poster_Image_Details"
android:id="@+id/posterImage"
android:layout_width="1dp"
android:layout_toLeftOf="@id/text_fields"
android:layout_toStartOf="@id/text_fields"
android:src="@mipmap/ic_launcher" />
<include layout="@layout/detail_text_fields"
android:id="@+id/text_fields"
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<RelativeLayout
android:id="@+id/detailRelative"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_marginTop="20dp"
android:layout_marginRight="10dp"
android:layout_marginEnd="10dp" />
<include layout="@layout/favorite_button"
android:id="@+id/favoriteButton"
android:layout_width="1px"
android:layout_height="wrap_content"
android:layout_alignLeft="@id/posterImage"
android:layout_alignStart="@id/posterImage"
android:layout_alignRight="@id/posterImage"
android:layout_alignEnd="@id/posterImage"
android:layout_below="@id/posterImage"/>
<!-- Mock Divider View. 1px to avoid half-pixel sizes on low-dpi screens! -->
<View
android:id="@+id/divider"
style="@style/divider" />
<TextView
android:id="@+id/overview"
android:layout_height="wrap_content">
<ImageView
style="@style/Poster_Image_Details"
android:id="@+id/posterImage"
android:layout_width="1dp"
android:layout_height="300dp"
android:layout_toLeftOf="@id/text_fields"
android:layout_toStartOf="@id/text_fields"
android:src="@mipmap/ic_launcher" />
<include layout="@layout/detail_text_fields"
android:id="@+id/text_fields"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_marginTop="20dp"
android:layout_marginRight="10dp"
android:layout_marginEnd="10dp" />
<include layout="@layout/favorite_button"
android:id="@+id/favoriteButton"
android:layout_width="1px"
android:layout_height="wrap_content"
android:layout_alignLeft="@id/posterImage"
android:layout_alignStart="@id/posterImage"
android:layout_alignRight="@id/posterImage"
android:layout_alignEnd="@id/posterImage"
android:layout_below="@id/posterImage"/>
<!-- Mock Divider View. 1px to avoid half-pixel sizes on low-dpi screens! -->
<View
android:id="@+id/divider"
style="@style/divider" />
<TextView
android:id="@+id/overview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/divider"
android:layout_margin="10dp"
android:padding="10dp"
android:elevation="4dp"
android:background="@color/colorPrimary"
android:textColor="@color/white"
android:text="In a land long ago and far far away."/>
</RelativeLayout>
<LinearLayout
android:id="@+id/trailerList"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/divider"
android:layout_margin="10dp"
android:padding="10dp"
android:elevation="4dp"
android:background="@color/colorPrimary"
android:textColor="@color/white"
android:text="In a land long ago and far far away."/>
</RelativeLayout>
android:orientation="vertical" />
<LinearLayout
android:id="@+id/reviewList"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:divider="@color/dividerColor"
android:dividerHeight="5dp"
android:orientation="vertical">
<TextView
android:id="@+id/reviewHeader"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:textAlignment="center"
android:textSize="36sp"
android:textColor="@color/primaryText"
android:text="@string/reviews_header"
android:visibility="gone"/>
</LinearLayout>
</LinearLayout>
</ScrollView>
</RelativeLayout>

View File

@@ -25,50 +25,77 @@
android:layout_height="match_parent"
android:background="@color/white"
android:clipToPadding="false">
<RelativeLayout
android:id="@+id/detailRelative"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
style="@style/Poster_Image_Details"
android:id="@+id/posterImage"
android:layout_width="wrap_content"
android:src="@mipmap/ic_launcher" />
<include layout="@layout/detail_text_fields"
android:id="@+id/text_fields"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@id/posterImage"
android:layout_toRightOf="@id/posterImage"
android:layout_toEndOf="@id/posterImage"
android:layout_marginTop="20dp"
android:layout_marginRight="10dp"
android:layout_marginEnd="10dp" />
<include layout="@layout/favorite_button"
android:id="@+id/favoriteButton"
android:layout_width="1px"
android:layout_height="wrap_content"
android:layout_alignLeft="@id/posterImage"
android:layout_alignStart="@id/posterImage"
android:layout_alignRight="@id/posterImage"
android:layout_alignEnd="@id/posterImage"
android:layout_below="@id/posterImage"
android:layout_marginBottom="5dp"/>
<TextView
android:id="@+id/overview"
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RelativeLayout
android:id="@+id/detailRelative"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
style="@style/Poster_Image_Details"
android:id="@+id/posterImage"
android:layout_width="wrap_content"
android:src="@mipmap/ic_launcher" />
<include layout="@layout/detail_text_fields"
android:id="@+id/text_fields"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@id/posterImage"
android:layout_toRightOf="@id/posterImage"
android:layout_toEndOf="@id/posterImage"
android:layout_marginTop="20dp"
android:layout_marginRight="10dp"
android:layout_marginEnd="10dp" />
<include layout="@layout/favorite_button"
android:id="@+id/favoriteButton"
android:layout_width="1px"
android:layout_height="wrap_content"
android:layout_alignLeft="@id/posterImage"
android:layout_alignStart="@id/posterImage"
android:layout_alignRight="@id/posterImage"
android:layout_alignEnd="@id/posterImage"
android:layout_below="@id/posterImage"
android:layout_marginBottom="5dp"/>
<TextView
android:id="@+id/overview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/text_fields"
android:layout_toRightOf="@id/posterImage"
android:layout_toEndOf="@id/posterImage"
android:layout_marginTop="10dp"
android:layout_marginRight="10dp"
android:layout_marginEnd="10dp"
android:padding="10dp"
android:elevation="4dp"
android:background="@color/colorPrimary"
android:textColor="@color/white"/>
</RelativeLayout>
<LinearLayout
android:id="@+id/trailerList"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/text_fields"
android:layout_toRightOf="@id/posterImage"
android:layout_toEndOf="@id/posterImage"
android:layout_marginTop="10dp"
android:layout_marginRight="10dp"
android:layout_marginEnd="10dp"
android:padding="10dp"
android:elevation="4dp"
android:background="@color/colorPrimary"
android:textColor="@color/white"
android:text="In a land long ago and far far away."/>
</RelativeLayout>
android:orientation="vertical" />
<LinearLayout
android:id="@+id/reviewList"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:divider="@color/dividerColor"
android:dividerHeight="5dp"
android:orientation="vertical">
<TextView
android:id="@+id/reviewHeader"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:textAlignment="center"
android:textSize="36sp"
android:textColor="@color/primaryText"
android:text="@string/reviews_header"
android:visibility="gone"/>
</LinearLayout>
</LinearLayout>
</ScrollView>
</RelativeLayout>

View File

@@ -16,6 +16,6 @@
android:background="@color/black"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2"
android:layout_weight="1"
android:elevation="8dp"/>
</LinearLayout>

View File

@@ -4,45 +4,41 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="@+id/releaseHeader"
style="@style/HeaderText"
android:id="@+id/releaseHeader"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"
android:text="Release Date: "/>
android:layout_alignParentLeft="true"/>
<TextView
android:id="@+id/releaseDate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/releaseHeader"
android:text="2016-01-29"/>
android:layout_toEndOf="@id/releaseHeader"/>
<TextView
style="@style/HeaderText"
android:id="@+id/ratingHeader"
android:layout_below="@id/releaseHeader"
android:layout_alignStart="@id/releaseHeader"
android:layout_alignLeft="@id/releaseHeader"
android:text="Rating: "/>
android:layout_alignLeft="@id/releaseHeader"/>
<TextView
android:id="@+id/rating"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toEndOf="@id/ratingHeader"
android:layout_toRightOf="@id/ratingHeader"
android:layout_alignTop="@id/ratingHeader"
android:text="7.7/10"/>
android:layout_alignTop="@id/ratingHeader"/>
<TextView
style="@style/HeaderText"
android:id="@+id/runtimeHeader"
android:layout_below="@id/ratingHeader"
android:layout_alignStart="@id/ratingHeader"
android:layout_alignLeft="@id/ratingHeader"
android:text="Runtime: "/>
android:layout_alignLeft="@id/ratingHeader"/>
<TextView
android:id="@+id/runtime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/runtimeHeader"
android:layout_toEndOf="@id/runtimeHeader"
android:layout_alignTop="@id/runtimeHeader"
android:text="123 minutes"/>
android:layout_alignTop="@id/runtimeHeader"/>
</RelativeLayout>

View File

@@ -25,51 +25,80 @@
android:layout_height="match_parent"
android:background="@color/white"
android:clipToPadding="false">
<RelativeLayout
android:id="@+id/detailRelative"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<include layout="@layout/detail_text_fields"
android:id="@+id/text_fields"
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<RelativeLayout
android:id="@+id/detailRelative"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_marginTop="20dp"
android:layout_marginRight="10dp"
android:layout_marginEnd="10dp" />
<ImageView
style="@style/Poster_Image_Details"
android:id="@+id/posterImage"
android:layout_width="1dp"
android:layout_toLeftOf="@id/text_fields"
android:layout_toStartOf="@id/text_fields"
android:src="@mipmap/ic_launcher" />
<include layout="@layout/favorite_button"
android:id="@+id/favoriteButton"
android:layout_width="1px"
android:layout_height="wrap_content"
android:layout_alignLeft="@id/posterImage"
android:layout_alignStart="@id/posterImage"
android:layout_alignRight="@id/posterImage"
android:layout_alignEnd="@id/posterImage"
android:layout_below="@id/posterImage"/>
<!-- Mock Divider View. 1px to avoid half-pixel sizes on low-dpi screens! -->
<View
android:id="@+id/divider"
style="@style/divider" />
<TextView
android:id="@+id/overview"
android:layout_height="wrap_content">
<include layout="@layout/detail_text_fields"
android:id="@+id/text_fields"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_marginTop="20dp"
android:layout_marginRight="10dp"
android:layout_marginEnd="10dp" />
<ImageView
style="@style/Poster_Image_Details"
android:id="@+id/posterImage"
android:layout_width="1dp"
android:layout_toLeftOf="@id/text_fields"
android:layout_toStartOf="@id/text_fields"
android:src="@mipmap/ic_launcher" />
<include layout="@layout/favorite_button"
android:id="@+id/favoriteButton"
android:layout_width="1px"
android:layout_height="wrap_content"
android:layout_alignLeft="@id/posterImage"
android:layout_alignStart="@id/posterImage"
android:layout_alignRight="@id/posterImage"
android:layout_alignEnd="@id/posterImage"
android:layout_below="@id/posterImage"/>
<!-- Mock Divider View. 1px to avoid half-pixel sizes on low-dpi screens! -->
<View
android:id="@+id/divider"
style="@style/divider" />
<TextView
android:id="@+id/overview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/divider"
android:layout_margin="10dp"
android:padding="10dp"
android:elevation="4dp"
android:background="@color/colorPrimary"
android:textColor="@color/white"
android:text="In a land long ago and far far away."/>
</RelativeLayout>
<LinearLayout
android:id="@+id/trailerList"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/divider"
android:layout_margin="10dp"
android:padding="10dp"
android:elevation="4dp"
android:background="@color/colorPrimary"
android:textColor="@color/white"
android:text="In a land long ago and far far away."/>
</RelativeLayout>
android:orientation="vertical" />
<LinearLayout
android:id="@+id/reviewList"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp"
android:divider="@android:color/transparent"
android:dividerHeight="5dp"
android:orientation="vertical">
<TextView
android:id="@+id/reviewHeader"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:textAlignment="center"
android:textSize="36sp"
android:textColor="@color/primaryText"
android:text="@string/reviews_header"
android:visibility="gone"/>
</LinearLayout>
</LinearLayout>
</ScrollView>
</RelativeLayout>

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/review"
android:background="@color/colorAccent"
android:elevation="2dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:padding="10dp"
android:textColor="@color/primaryText"
android:text="Testing Text"/>

View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:orientation="horizontal">
<ImageView
android:layout_width="96dp"
android:layout_height="96dp"
android:adjustViewBounds="true"
android:scaleType="fitXY"
android:src="@drawable/trailer_icon"/>
<TextView
android:id="@+id/trailerText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginLeft="10dp"
android:layout_marginStart="10dp"
android:textAlignment="center"
android:textSize="32sp"
android:gravity="center"
android:layout_gravity="center_vertical"/>
</LinearLayout>

View File

@@ -2,6 +2,7 @@
<string name="app_name">Popular Movies</string>
<string name="action_settings">Settings</string>
<string name="settings_activity_title">Settings</string>
<string name="action_share">Share</string>
<!-- Strings related to Settings -->
<string name="pref_sort_key">Sort_By</string>
@@ -14,6 +15,8 @@
<string name="pref_sort_favorite_value">Favorites</string>
<string name="get_move_button_label">Get More Movies</string>
<string name="out_of_ten">/10</string>
<string name="reviews_header">Reviews</string>
<string name="runtime_unit">" minutes"</string>
<array name="pref_sort_labels">
<item name="pref_sort_popularity_label">Popularity</item>