stashing
@@ -1,5 +1,6 @@
|
|||||||
package net.headlezz.udacityproject1;
|
package net.headlezz.udacityproject1;
|
||||||
|
|
||||||
|
import android.app.ProgressDialog;
|
||||||
import android.content.ActivityNotFoundException;
|
import android.content.ActivityNotFoundException;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
@@ -21,6 +22,7 @@ import android.widget.Toast;
|
|||||||
|
|
||||||
import net.headlezz.udacityproject1.favorites.FavoriteProviderHelper;
|
import net.headlezz.udacityproject1.favorites.FavoriteProviderHelper;
|
||||||
import net.headlezz.udacityproject1.tmdbapi.Movie;
|
import net.headlezz.udacityproject1.tmdbapi.Movie;
|
||||||
|
import net.headlezz.udacityproject1.tmdbapi.ReviewList;
|
||||||
import net.headlezz.udacityproject1.tmdbapi.TMDBApi;
|
import net.headlezz.udacityproject1.tmdbapi.TMDBApi;
|
||||||
import net.headlezz.udacityproject1.tmdbapi.Video;
|
import net.headlezz.udacityproject1.tmdbapi.Video;
|
||||||
import net.headlezz.udacityproject1.tmdbapi.VideoList;
|
import net.headlezz.udacityproject1.tmdbapi.VideoList;
|
||||||
@@ -29,6 +31,7 @@ import java.util.List;
|
|||||||
|
|
||||||
import butterknife.Bind;
|
import butterknife.Bind;
|
||||||
import butterknife.ButterKnife;
|
import butterknife.ButterKnife;
|
||||||
|
import butterknife.OnClick;
|
||||||
import retrofit.Call;
|
import retrofit.Call;
|
||||||
import retrofit.Callback;
|
import retrofit.Callback;
|
||||||
import retrofit.Response;
|
import retrofit.Response;
|
||||||
@@ -133,6 +136,32 @@ public class MovieDetailsFragment extends Fragment implements Callback<VideoList
|
|||||||
|
|
||||||
// TODO high res image for video link
|
// TODO high res image for video link
|
||||||
|
|
||||||
|
@OnClick(R.id.movie_details_btReviews)
|
||||||
|
public void onReviewButtonClick(View view) {
|
||||||
|
// TODO progressdialogs are bad because of rotation
|
||||||
|
final ProgressDialog dialog = new ProgressDialog(getContext());
|
||||||
|
dialog.setIndeterminate(true);
|
||||||
|
dialog.show();
|
||||||
|
TMDBApi.getReviewsForMovie(mMovie, getString(R.string.api_key)).enqueue(new Callback<ReviewList>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Response<ReviewList> response, Retrofit retrofit) {
|
||||||
|
dialog.dismiss();
|
||||||
|
if(response.isSuccess()) {
|
||||||
|
ReviewDialogFragment frag = ReviewDialogFragment.newInstance(response.body());
|
||||||
|
frag.show(getChildFragmentManager(), ReviewDialogFragment.TAG);
|
||||||
|
} else {
|
||||||
|
Log.e(TAG, "Query not successful.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Throwable t) {
|
||||||
|
dialog.dismiss();
|
||||||
|
Log.e(TAG, "something went wrong: " + t.getMessage());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* shows a list of links to youtube videos for the selected movie
|
* shows a list of links to youtube videos for the selected movie
|
||||||
* if the videolist has no videos, the user sees a message that there are no.
|
* if the videolist has no videos, the user sees a message that there are no.
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
package net.headlezz.udacityproject1;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
import android.support.v4.app.DialogFragment;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import net.headlezz.udacityproject1.tmdbapi.ReviewList;
|
||||||
|
|
||||||
|
import butterknife.Bind;
|
||||||
|
import butterknife.ButterKnife;
|
||||||
|
|
||||||
|
public class ReviewDialogFragment extends DialogFragment {
|
||||||
|
|
||||||
|
public static final String TAG = ReviewDialogFragment.class.getSimpleName();
|
||||||
|
public static final String BUNDLE_ARG_REVIEWLIST = "reviewlist";
|
||||||
|
|
||||||
|
ReviewList mReviewList;
|
||||||
|
|
||||||
|
@Bind(R.id.review_tvReview)
|
||||||
|
TextView tvReview;
|
||||||
|
|
||||||
|
public static ReviewDialogFragment newInstance(ReviewList reviews) {
|
||||||
|
ReviewDialogFragment frag = new ReviewDialogFragment();
|
||||||
|
Bundle args = new Bundle();
|
||||||
|
args.putParcelable(BUNDLE_ARG_REVIEWLIST, reviews);
|
||||||
|
frag.setArguments(args);
|
||||||
|
return frag;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
if(getArguments() != null && getArguments().containsKey(BUNDLE_ARG_REVIEWLIST))
|
||||||
|
mReviewList = getArguments().getParcelable(BUNDLE_ARG_REVIEWLIST);
|
||||||
|
else
|
||||||
|
throw new RuntimeException("No arguments found");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||||
|
View dialogView = inflater.inflate(R.layout.movie_details_review_dialog, container, false);
|
||||||
|
ButterKnife.bind(this, dialogView);
|
||||||
|
tvReview.setText(mReviewList.getReviews().get(0).getContent());
|
||||||
|
return dialogView;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
package net.headlezz.udacityproject1.tmdbapi;
|
||||||
|
|
||||||
|
import android.os.Parcel;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
|
||||||
|
public class Review implements Parcelable {
|
||||||
|
|
||||||
|
String author;
|
||||||
|
String content;
|
||||||
|
|
||||||
|
public String getAuthor() {
|
||||||
|
return author;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getContent() {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int describeContents() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeToParcel(Parcel parcel, int i) {
|
||||||
|
parcel.writeString(author);
|
||||||
|
parcel.writeString(content);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final Parcelable.Creator<Review> CREATOR = new Parcelable.Creator<Review>() {
|
||||||
|
public Review createFromParcel(Parcel src) {
|
||||||
|
return new Review(src);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Review[] newArray(int size) {
|
||||||
|
return new Review[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Review(Parcel in) {
|
||||||
|
this.author = in.readString();
|
||||||
|
this.content = in.readString();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
package net.headlezz.udacityproject1.tmdbapi;
|
||||||
|
|
||||||
|
import android.os.Parcel;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ReviewList implements Parcelable {
|
||||||
|
|
||||||
|
List<Review> reviews;
|
||||||
|
|
||||||
|
public ReviewList(List<Review> reviews) {
|
||||||
|
this.reviews = reviews;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Review> getReviews() {
|
||||||
|
return reviews;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int describeContents() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeToParcel(Parcel parcel, int i) {
|
||||||
|
parcel.writeList(reviews);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final Parcelable.Creator<ReviewList> CREATOR = new Parcelable.Creator<ReviewList>() {
|
||||||
|
public ReviewList createFromParcel(Parcel src) {
|
||||||
|
return new ReviewList(src);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ReviewList[] newArray(int size) {
|
||||||
|
return new ReviewList[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private ReviewList(Parcel src) {
|
||||||
|
this.reviews = src.readArrayList(Review.class.getClassLoader());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package net.headlezz.udacityproject1.tmdbapi;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.JsonDeserializationContext;
|
||||||
|
import com.google.gson.JsonDeserializer;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonParseException;
|
||||||
|
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ReviewListDeserializer implements JsonDeserializer<ReviewList> {
|
||||||
|
@Override
|
||||||
|
public ReviewList deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
||||||
|
Gson gson = new Gson();
|
||||||
|
List<Review> reviews = new ArrayList<>();
|
||||||
|
for(JsonElement elem : json.getAsJsonObject().getAsJsonArray("results")) {
|
||||||
|
reviews.add(gson.fromJson(elem, Review.class));
|
||||||
|
}
|
||||||
|
return new ReviewList(reviews);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -41,6 +41,7 @@ public class TMDBApi {
|
|||||||
Gson gson = new GsonBuilder()
|
Gson gson = new GsonBuilder()
|
||||||
.registerTypeAdapter(MovieList.class, new MovieListDeserializer())
|
.registerTypeAdapter(MovieList.class, new MovieListDeserializer())
|
||||||
.registerTypeAdapter(VideoList.class, new VideoListDeserializer())
|
.registerTypeAdapter(VideoList.class, new VideoListDeserializer())
|
||||||
|
.registerTypeAdapter(ReviewList.class, new ReviewListDeserializer())
|
||||||
.create();
|
.create();
|
||||||
Retrofit retrofit = new Retrofit.Builder()
|
Retrofit retrofit = new Retrofit.Builder()
|
||||||
.baseUrl(BASE_URL)
|
.baseUrl(BASE_URL)
|
||||||
@@ -69,6 +70,10 @@ public class TMDBApi {
|
|||||||
return apiService.getVideosForMovie(movie.getId(), apiKey);
|
return apiService.getVideosForMovie(movie.getId(), apiKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Call<ReviewList> getReviewsForMovie(Movie movie, String apiKey) {
|
||||||
|
return apiService.getReviewsForMovie(movie.getId(), apiKey);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Api interface for retrofit
|
* Api interface for retrofit
|
||||||
*/
|
*/
|
||||||
@@ -80,6 +85,10 @@ public class TMDBApi {
|
|||||||
@Headers("Accept: application/json")
|
@Headers("Accept: application/json")
|
||||||
@GET("movie/{id}/videos")
|
@GET("movie/{id}/videos")
|
||||||
Call<VideoList> getVideosForMovie(@Path("id") long id, @Query("api_key") String apiKey);
|
Call<VideoList> getVideosForMovie(@Path("id") long id, @Query("api_key") String apiKey);
|
||||||
|
|
||||||
|
@Headers("Accept: application/json")
|
||||||
|
@GET("movie/{id}/reviews")
|
||||||
|
Call<ReviewList> getReviewsForMovie(@Path("id") long id, @Query("api_key") String apiKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
app/src/main/res/drawable-hdpi/ic_action_arrow_left.png
Normal file
|
After Width: | Height: | Size: 343 B |
BIN
app/src/main/res/drawable-hdpi/ic_action_arrow_right.png
Normal file
|
After Width: | Height: | Size: 352 B |
BIN
app/src/main/res/drawable-ldpi/ic_action_arrow_left.png
Normal file
|
After Width: | Height: | Size: 247 B |
BIN
app/src/main/res/drawable-ldpi/ic_action_arrow_right.png
Normal file
|
After Width: | Height: | Size: 246 B |
BIN
app/src/main/res/drawable-mdpi/ic_action_arrow_left.png
Normal file
|
After Width: | Height: | Size: 289 B |
BIN
app/src/main/res/drawable-mdpi/ic_action_arrow_right.png
Normal file
|
After Width: | Height: | Size: 295 B |
BIN
app/src/main/res/drawable-tvdpi/ic_action_arrow_left.png
Normal file
|
After Width: | Height: | Size: 523 B |
BIN
app/src/main/res/drawable-tvdpi/ic_action_arrow_right.png
Normal file
|
After Width: | Height: | Size: 505 B |
BIN
app/src/main/res/drawable-xhdpi/ic_action_arrow_left.png
Normal file
|
After Width: | Height: | Size: 432 B |
BIN
app/src/main/res/drawable-xhdpi/ic_action_arrow_right.png
Normal file
|
After Width: | Height: | Size: 441 B |
BIN
app/src/main/res/drawable-xxhdpi/ic_action_arrow_left.png
Normal file
|
After Width: | Height: | Size: 563 B |
BIN
app/src/main/res/drawable-xxhdpi/ic_action_arrow_right.png
Normal file
|
After Width: | Height: | Size: 567 B |
BIN
app/src/main/res/drawable-xxxhdpi/ic_action_arrow_left.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
app/src/main/res/drawable-xxxhdpi/ic_action_arrow_right.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
@@ -2,8 +2,7 @@
|
|||||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent">
|
||||||
xmlns:andorid="http://schemas.android.com/apk/res-auto">
|
|
||||||
|
|
||||||
<RelativeLayout
|
<RelativeLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@@ -83,5 +82,13 @@
|
|||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Reviews"
|
||||||
|
android:id="@+id/movie_details_btReviews"
|
||||||
|
android:layout_alignBottom="@+id/movie_details_ivPoster"
|
||||||
|
android:layout_alignStart="@+id/movie_details_tvRating" />
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
42
app/src/main/res/layout/movie_details_review_dialog.xml
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<ScrollView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="250dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/review_tvReview"
|
||||||
|
tools:text="Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet."
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
|
</ScrollView>
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:tint="@android:color/white"
|
||||||
|
android:background="@android:color/transparent"
|
||||||
|
android:layout_gravity="left"
|
||||||
|
android:src="@drawable/ic_action_arrow_left"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:tint="@color/colorAccent"
|
||||||
|
android:background="@android:color/transparent"
|
||||||
|
android:layout_gravity="right"
|
||||||
|
android:src="@drawable/ic_action_arrow_right"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||