Start of basic details

This commit is contained in:
Eric Reed committed 2014-12-08 11:00:57 -05:00
1 parent 47faaa81f8
commit 393ba2ca8d
9 files changed
+244 -199

No files matched your search

@@ -45,6 +45,11 @@
android:name="tv.mediabrowser.mediabrowsertv.SelectUserActivity"
android:label="@string/title_activity_select_user" >
</activity>
<activity android:name=".PlaybackOverlayActivity"
android:label="PlaybackOverlayActivity" >
</activity>
<activity android:name=".BrowseErrorActivity" ></activity>
</application>
</manifest>
@@ -0,0 +1,197 @@
package tv.mediabrowser.mediabrowsertv;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v17.leanback.app.BackgroundManager;
import android.support.v17.leanback.app.DetailsFragment;
import android.support.v17.leanback.widget.Action;
import android.support.v17.leanback.widget.ArrayObjectAdapter;
import android.support.v17.leanback.widget.ClassPresenterSelector;
import android.support.v17.leanback.widget.DetailsOverviewRow;
import android.support.v17.leanback.widget.DetailsOverviewRowPresenter;
import android.support.v17.leanback.widget.HeaderItem;
import android.support.v17.leanback.widget.ImageCardView;
import android.support.v17.leanback.widget.ListRow;
import android.support.v17.leanback.widget.ListRowPresenter;
import android.support.v17.leanback.widget.OnActionClickedListener;
import android.support.v17.leanback.widget.OnItemViewClickedListener;
import android.support.v17.leanback.widget.Presenter;
import android.support.v17.leanback.widget.Row;
import android.support.v17.leanback.widget.RowPresenter;
import android.support.v4.app.ActivityOptionsCompat;
import android.util.DisplayMetrics;
import android.util.Log;
import android.widget.Toast;
import com.squareup.picasso.Picasso;
import com.squareup.picasso.Target;
import mediabrowser.apiinteraction.ApiClient;
import mediabrowser.model.dto.BaseItemDto;
public class BaseItemDetailsFragment extends DetailsFragment {
private static final String TAG = "BaseItemDetailsFragment";
private static final int ACTION_WATCH_TRAILER = 1;
private static final int ACTION_RENT = 2;
private static final int ACTION_BUY = 3;
private static final int DETAIL_THUMB_WIDTH = 274;
private static final int DETAIL_THUMB_HEIGHT = 274;
private static final int NUM_COLS = 10;
private BaseItemDto mBaseItem;
private ApiClient mApiClient;
private Drawable mDefaultBackground;
private Target mBackgroundTarget;
private DisplayMetrics mMetrics;
private DetailsOverviewRowPresenter mDorPresenter;
private DetailRowBuilderTask mDetailRowBuilderTask;
@Override
public void onCreate(Bundle savedInstanceState) {
Log.i(TAG, "onCreate DetailsFragment");
super.onCreate(savedInstanceState);
mDorPresenter =
new DetailsOverviewRowPresenter(new DetailsDescriptionPresenter());
BackgroundManager backgroundManager = BackgroundManager.getInstance(getActivity());
backgroundManager.attach(getActivity().getWindow());
mBackgroundTarget = new PicassoBackgroundManagerTarget(backgroundManager);
mDefaultBackground = getResources().getDrawable(R.drawable.default_background);
mMetrics = new DisplayMetrics();
getActivity().getWindowManager().getDefaultDisplay().getMetrics(mMetrics);
mBaseItem = TvApp.getApplication().getSerializer().DeserializeFromString(getActivity().getIntent().getStringExtra("BaseItemDto"),BaseItemDto.class);
mDetailRowBuilderTask = (DetailRowBuilderTask) new DetailRowBuilderTask().execute(mBaseItem);
mDorPresenter.setSharedElementEnterTransition(getActivity(),
DetailsActivity.SHARED_ELEMENT_NAME);
mApiClient = TvApp.getApplication().getApiClient();
updateBackground(Utils.getBackdropImageUrl(mBaseItem, TvApp.getApplication().getApiClient()));
setOnItemViewClickedListener(new ItemViewClickedListener());
}
@Override
public void onStop() {
mDetailRowBuilderTask.cancel(true);
super.onStop();
}
private class DetailRowBuilderTask extends AsyncTask<BaseItemDto, Integer, DetailsOverviewRow> {
@Override
protected DetailsOverviewRow doInBackground(BaseItemDto... baseItem) {
BaseItemDetailsFragment.this.mBaseItem = baseItem[0];
DetailsOverviewRow row = new DetailsOverviewRow(BaseItemDetailsFragment.this.mBaseItem);
try {
Bitmap poster = Picasso.with(getActivity())
.load(Utils.getPrimaryImageUrl(BaseItemDetailsFragment.this.mBaseItem, mApiClient))
.resize(Utils.convertDpToPixel(getActivity().getApplicationContext(), DETAIL_THUMB_WIDTH),
Utils.convertDpToPixel(getActivity().getApplicationContext(), DETAIL_THUMB_HEIGHT))
.centerCrop()
.get();
row.setImageBitmap(getActivity(), poster);
} catch (IOException e) {
}
row.addAction(new Action(ACTION_WATCH_TRAILER, getResources().getString(
R.string.watch_trailer_1), getResources().getString(R.string.watch_trailer_2)));
row.addAction(new Action(ACTION_RENT, getResources().getString(R.string.rent_1),
getResources().getString(R.string.rent_2)));
row.addAction(new Action(ACTION_BUY, getResources().getString(R.string.buy_1),
getResources().getString(R.string.buy_2)));
return row;
}
@Override
protected void onPostExecute(DetailsOverviewRow detailRow) {
ClassPresenterSelector ps = new ClassPresenterSelector();
// set detail background and style
mDorPresenter.setBackgroundColor(getResources().getColor(R.color.detail_background));
mDorPresenter.setStyleLarge(true);
mDorPresenter.setOnActionClickedListener(new OnActionClickedListener() {
@Override
public void onActionClicked(Action action) {
if (action.getId() == ACTION_WATCH_TRAILER) {
Intent intent = new Intent(getActivity(), PlaybackOverlayActivity.class);
intent.putExtra("BaseItemDto", TvApp.getApplication().getSerializer().SerializeToString(mBaseItem));
intent.putExtra(getResources().getString(R.string.should_start), true);
startActivity(intent);
} else {
Toast.makeText(getActivity(), action.toString(), Toast.LENGTH_SHORT).show();
}
}
});
ps.addClassPresenter(DetailsOverviewRow.class, mDorPresenter);
ps.addClassPresenter(ListRow.class,
new ListRowPresenter());
ArrayObjectAdapter adapter = new ArrayObjectAdapter(ps);
adapter.add(detailRow);
// String subcategories[] = {
// getString(R.string.related_movies)
// };
// List<Movie> list = MovieList.list;
// Collections.shuffle(list);
// ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(new CardPresenter());
// for (int j = 0; j < NUM_COLS; j++) {
// listRowAdapter.add(list.get(j % 5));
// }
//
// HeaderItem header = new HeaderItem(0, subcategories[0], null);
// adapter.add(new ListRow(header, listRowAdapter));
setAdapter(adapter);
}
}
private final class ItemViewClickedListener implements OnItemViewClickedListener {
@Override
public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item,
RowPresenter.ViewHolder rowViewHolder, Row row) {
if (item instanceof Movie) {
Movie movie = (Movie) item;
Log.d(TAG, "Item: " + item.toString());
Intent intent = new Intent(getActivity(), DetailsActivity.class);
intent.putExtra(DetailsActivity.MOVIE, movie);
Bundle bundle = ActivityOptionsCompat.makeSceneTransitionAnimation(
getActivity(),
((ImageCardView) itemViewHolder.view).getMainImageView(),
DetailsActivity.SHARED_ELEMENT_NAME).toBundle();
getActivity().startActivity(intent, bundle);
}
}
}
protected void updateBackground(String url) {
Log.d(TAG, "url" + url);
Log.d(TAG, "metrics" + mMetrics.toString());
Picasso.with(getActivity())
.load(url)
.resize(mMetrics.widthPixels, mMetrics.heightPixels)
.error(mDefaultBackground)
.into(mBackgroundTarget);
}
}
@@ -2,15 +2,17 @@ package tv.mediabrowser.mediabrowsertv;
import android.support.v17.leanback.widget.AbstractDetailsDescriptionPresenter;
import mediabrowser.model.dto.BaseItemDto;
public class DetailsDescriptionPresenter extends AbstractDetailsDescriptionPresenter {
@Override
protected void onBindDescription(ViewHolder viewHolder, Object item) {
Movie movie = (Movie) item;
BaseItemDto baseItem = (BaseItemDto) item;
if (movie != null) {
viewHolder.getTitle().setText(movie.getTitle());
viewHolder.getSubtitle().setText(movie.getStudio());
viewHolder.getBody().setText(movie.getDescription());
if (baseItem != null) {
viewHolder.getTitle().setText(baseItem.getName());
viewHolder.getSubtitle().setText(baseItem.getOfficialRating());
viewHolder.getBody().setText(baseItem.getOverview());
}
}
}
@@ -95,8 +95,8 @@ public class HomeFragment extends StdBrowseFragment {
Intent intent = new Intent(getActivity(), BrowseErrorActivity.class);
startActivity(intent);
} else if (((String) item).indexOf("Logout ") >= 0) {
apiClient = TvApp.getApplication().getConnectionManager().GetApiClient(TvApp.getApplication().getCurrentUser());
apiClient.Logout(new EmptyResponse() {
mApiClient = TvApp.getApplication().getConnectionManager().GetApiClient(TvApp.getApplication().getCurrentUser());
mApiClient.Logout(new EmptyResponse() {
@Override
public void onResponse() {
super.onResponse();
@@ -63,7 +63,7 @@ public class StartupActivity extends Activity {
apiEventListener);
application.setConnectionManager(connectionManager);
application.setSerializer(jsonSerializer);
application.setSerializer((GsonJsonSerializer)jsonSerializer);
connectionManager.Connect(new Response<ConnectionResult>() {
@Override
@@ -45,6 +45,7 @@ import java.util.Timer;
import java.util.TimerTask;
import mediabrowser.apiinteraction.ApiClient;
import mediabrowser.apiinteraction.Response;
import mediabrowser.model.dto.BaseItemDto;
@@ -54,7 +55,8 @@ public class StdBrowseFragment extends BrowseFragment {
private static final int BACKGROUND_UPDATE_DELAY = 200;
protected String MainTitle;
protected ApiClient apiClient;
protected ApiClient mApiClient;
protected TvApp mApplication;
protected CompositeClickedListener mClickedListener = new CompositeClickedListener();
protected CompositeSelectedListener mSelectedListener = new CompositeSelectedListener();
private ArrayObjectAdapter mRowsAdapter;
@@ -72,6 +74,8 @@ public class StdBrowseFragment extends BrowseFragment {
Log.i(TAG, "onCreate");
super.onActivityCreated(savedInstanceState);
mApplication = TvApp.getApplication();
prepareBackgroundManager();
setupUIElements();
@@ -175,20 +179,33 @@ public class StdBrowseFragment extends BrowseFragment {
private final class ItemViewClickedListener implements OnItemViewClickedListener {
@Override
public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item,
public void onItemClicked(final Presenter.ViewHolder itemViewHolder, Object item,
RowPresenter.ViewHolder rowViewHolder, Row row) {
if (item instanceof BaseItemDto) {
BaseItemDto baseItem = (BaseItemDto) item;
final BaseItemDto baseItem = (BaseItemDto) item;
TvApp.getApplication().getLogger().Debug("Item selected: " + item.toString());
Intent intent = new Intent(getActivity(), DetailsActivity.class);
intent.putExtra("BaseItemDto", TvApp.getApplication().getSerializer().SerializeToString(baseItem));
//Retrieve full item for display and playback
mApplication.getApiClient().GetItemAsync(baseItem.getId(), mApplication.getCurrentUser().getId(), new Response<BaseItemDto>() {
@Override
public void onResponse(BaseItemDto response) {
Intent intent = new Intent(getActivity(), DetailsActivity.class);
intent.putExtra("BaseItemDto", TvApp.getApplication().getSerializer().SerializeToString(response));
Bundle bundle = ActivityOptionsCompat.makeSceneTransitionAnimation(
getActivity(),
((ImageCardView) itemViewHolder.view).getMainImageView(),
DetailsActivity.SHARED_ELEMENT_NAME).toBundle();
getActivity().startActivity(intent, bundle);
Bundle bundle = ActivityOptionsCompat.makeSceneTransitionAnimation(
getActivity(),
((ImageCardView) itemViewHolder.view).getMainImageView(),
DetailsActivity.SHARED_ELEMENT_NAME).toBundle();
getActivity().startActivity(intent, bundle);
}
@Override
public void onError(Exception exception) {
mApplication.getLogger().ErrorException("Error retrieving full object", exception);
exception.printStackTrace();
}
});
}
}
}
@@ -5,6 +5,7 @@ import android.util.Log;
import mediabrowser.apiinteraction.ApiClient;
import mediabrowser.apiinteraction.IConnectionManager;
import mediabrowser.apiinteraction.android.GsonJsonSerializer;
import mediabrowser.logging.ConsoleLogger;
import mediabrowser.model.dto.UserDto;
import mediabrowser.model.logging.ILogger;
@@ -17,7 +18,7 @@ public class TvApp extends Application {
private ILogger logger;
private IConnectionManager connectionManager;
private IJsonSerializer serializer;
private GsonJsonSerializer serializer;
private static TvApp app;
private UserDto currentUser;
@@ -65,11 +66,11 @@ public class TvApp extends Application {
this.currentUser = currentUser;
}
public IJsonSerializer getSerializer() {
public GsonJsonSerializer getSerializer() {
return serializer;
}
public void setSerializer(IJsonSerializer serializer) {
public void setSerializer(GsonJsonSerializer serializer) {
this.serializer = serializer;
}
@@ -1,177 +0,0 @@
package tv.mediabrowser.mediabrowsertv;
import java.io.IOException;
import java.net.URI;
import java.util.Collections;
import java.util.List;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v17.leanback.app.BackgroundManager;
import android.support.v17.leanback.app.DetailsFragment;
import android.support.v17.leanback.widget.Action;
import android.support.v17.leanback.widget.ArrayObjectAdapter;
import android.support.v17.leanback.widget.ClassPresenterSelector;
import android.support.v17.leanback.widget.DetailsOverviewRow;
import android.support.v17.leanback.widget.DetailsOverviewRowPresenter;
import android.support.v17.leanback.widget.HeaderItem;
import android.support.v17.leanback.widget.ListRow;
import android.support.v17.leanback.widget.ListRowPresenter;
import android.support.v17.leanback.widget.OnActionClickedListener;
import android.support.v17.leanback.widget.OnItemClickedListener;
import android.support.v17.leanback.widget.Row;
import android.util.DisplayMetrics;
import android.util.Log;
import android.widget.Toast;
import com.squareup.picasso.Picasso;
import com.squareup.picasso.Target;
public class VideoDetailsFragment extends DetailsFragment {
private static final String TAG = "VideoDetailsFragment";
private static final int ACTION_WATCH_TRAILER = 1;
private static final int ACTION_RENT = 2;
private static final int ACTION_BUY = 3;
private static final int DETAIL_THUMB_WIDTH = 274;
private static final int DETAIL_THUMB_HEIGHT = 274;
private static final int NUM_COLS = 10;
private static final String MOVIE = "Movie";
private Movie selectedMovie;
private Drawable mDefaultBackground;
private Target mBackgroundTarget;
private DisplayMetrics mMetrics;
@Override
public void onCreate(Bundle savedInstanceState) {
Log.i(TAG, "onCreate DetailsFragment");
super.onCreate(savedInstanceState);
BackgroundManager backgroundManager = BackgroundManager.getInstance(getActivity());
backgroundManager.attach(getActivity().getWindow());
mBackgroundTarget = new PicassoBackgroundManagerTarget(backgroundManager);
mDefaultBackground = getResources().getDrawable(R.drawable.default_background);
mMetrics = new DisplayMetrics();
getActivity().getWindowManager().getDefaultDisplay().getMetrics(mMetrics);
selectedMovie = (Movie) getActivity().getIntent().getSerializableExtra(MOVIE);
new DetailRowBuilderTask().execute(selectedMovie);
setOnItemClickedListener(getDefaultItemClickedListener());
updateBackground(selectedMovie.getBackgroundImageURI());
}
private class DetailRowBuilderTask extends AsyncTask<Movie, Integer, DetailsOverviewRow> {
@Override
protected DetailsOverviewRow doInBackground(Movie... movies) {
selectedMovie = movies[0];
DetailsOverviewRow row = new DetailsOverviewRow(selectedMovie);
try {
Bitmap poster = Picasso.with(getActivity())
.load(selectedMovie.getCardImageUrl())
.resize(dpToPx(DETAIL_THUMB_WIDTH, getActivity().getApplicationContext()),
dpToPx(DETAIL_THUMB_HEIGHT, getActivity().getApplicationContext()))
.centerCrop()
.get();
row.setImageBitmap(getActivity(), poster);
} catch (IOException e) {
}
row.addAction(new Action(ACTION_WATCH_TRAILER, getResources().getString(
R.string.watch_trailer_1), getResources().getString(R.string.watch_trailer_2)));
row.addAction(new Action(ACTION_RENT, getResources().getString(R.string.rent_1),
getResources().getString(R.string.rent_2)));
row.addAction(new Action(ACTION_BUY, getResources().getString(R.string.buy_1),
getResources().getString(R.string.buy_2)));
return row;
}
@Override
protected void onPostExecute(DetailsOverviewRow detailRow) {
ClassPresenterSelector ps = new ClassPresenterSelector();
DetailsOverviewRowPresenter dorPresenter =
new DetailsOverviewRowPresenter(new DetailsDescriptionPresenter());
// set detail background and style
dorPresenter.setBackgroundColor(getResources().getColor(R.color.detail_background));
dorPresenter.setStyleLarge(true);
dorPresenter.setOnActionClickedListener(new OnActionClickedListener() {
@Override
public void onActionClicked(Action action) {
if (action.getId() == ACTION_WATCH_TRAILER) {
Intent intent = new Intent(getActivity(), PlayerActivity.class);
intent.putExtra(getResources().getString(R.string.movie), selectedMovie);
intent.putExtra(getResources().getString(R.string.should_start), true);
startActivity(intent);
} else {
Toast.makeText(getActivity(), action.toString(), Toast.LENGTH_SHORT).show();
}
}
});
ps.addClassPresenter(DetailsOverviewRow.class, dorPresenter);
ps.addClassPresenter(ListRow.class,
new ListRowPresenter());
ArrayObjectAdapter adapter = new ArrayObjectAdapter(ps);
adapter.add(detailRow);
String subcategories[] = {
getString(R.string.related_movies)
};
List<Movie> list = MovieList.list;
Collections.shuffle(list);
ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(new CardPresenter());
for (int j = 0; j < NUM_COLS; j++) {
listRowAdapter.add(list.get(j % 5));
}
HeaderItem header = new HeaderItem(0, subcategories[0], null);
adapter.add(new ListRow(header, listRowAdapter));
setAdapter(adapter);
}
}
protected OnItemClickedListener getDefaultItemClickedListener() {
return new OnItemClickedListener() {
@Override
public void onItemClicked(Object item, Row row) {
if (item instanceof Movie) {
Movie movie = (Movie) item;
Intent intent = new Intent(getActivity(), DetailsActivity.class);
intent.putExtra(MOVIE, movie);
startActivity(intent);
}
}
};
}
protected void updateBackground(URI uri) {
Log.d(TAG, "uri" + uri);
Log.d(TAG, "metrics" + mMetrics.toString());
Picasso.with(getActivity())
.load(uri.toString())
.resize(mMetrics.widthPixels, mMetrics.heightPixels)
.error(mDefaultBackground)
.into(mBackgroundTarget);
}
public static int dpToPx(int dp, Context ctx) {
float density = ctx.getResources().getDisplayMetrics().density;
return Math.round((float) dp * density);
}
}
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:id="@+id/details_fragment"
android:name="tv.mediabrowser.mediabrowsertv.VideoDetailsFragment"
android:name="tv.mediabrowser.mediabrowsertv.BaseItemDetailsFragment"
android:layout_width="match_parent" android:layout_height="match_parent"
tools:context=".DetailsActivity" tools:deviceIds="tv" />