From e6b72719a85a4731673d1d56f7b4f7463f18e249 Mon Sep 17 00:00:00 2001 From: Robert Hahn Date: Tue, 18 Aug 2015 11:46:53 -0700 Subject: [PATCH] Added Transitions and minor code clean up Added support for the DetailView Activity transition. The DetailView can now be started from the launcher or the Cards example. Added support for Browse entrance transition. Minor code clean up such as renaming GridExample fragment to GridExampleFragment and removing unused methods. Change-Id: Ib1c11af82be5b858960e243acd7f11ce8dbd06f7 --- .../app/src/main/AndroidManifest.xml | 4 +- .../app/MainFragment.java | 3 +- .../app/cards/CardExampleFragment.java | 55 ++++++++++++++++--- .../details/DetailViewExampleFragment.java | 29 +++++++++- ...dExample.java => GridExampleFragment.java} | 2 +- .../wizard/WizardExample1stStepFragment.java | 2 + .../wizard/WizardExample2ndStepFragment.java | 3 + .../wizard/WizardExample4thStepFragment.java | 2 + .../cards/CharacterCardView.java | 1 + .../supportleanbackshowcase/utils/Utils.java | 37 ------------- .../res/layout/activity_cards_example.xml | 1 + .../res/layout/activity_detail_example.xml | 1 + .../main/res/layout/activity_grid_example.xml | 2 +- .../src/main/res/layout/character_card.xml | 1 + .../app/src/main/res/values/styles.xml | 2 +- .../app/src/main/res/values/themes.xml | 5 +- 16 files changed, 95 insertions(+), 55 deletions(-) rename samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/grid/{GridExample.java => GridExampleFragment.java} (97%) diff --git a/samples/SupportLeanbackShowcase/app/src/main/AndroidManifest.xml b/samples/SupportLeanbackShowcase/app/src/main/AndroidManifest.xml index df351806c..756ef94e7 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/AndroidManifest.xml +++ b/samples/SupportLeanbackShowcase/app/src/main/AndroidManifest.xml @@ -41,10 +41,10 @@ android:theme="@style/Theme.Example.LeanbackDialog"> + android:theme="@style/Theme.Example.LeanbackDetails"> + android:theme="@style/Theme.Example.LeanbackBrowse"> diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/MainFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/MainFragment.java index 1288a3797..ab22928d8 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/MainFragment.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/MainFragment.java @@ -164,8 +164,7 @@ public class MainFragment extends BrowseFragment { break; } if (intent != null) { - Bundle bundle = ActivityOptionsCompat.makeSceneTransitionAnimation(getActivity(), - ((ImageCardView) itemViewHolder.view).getMainImageView(), "transition") + Bundle bundle = ActivityOptionsCompat.makeSceneTransitionAnimation(getActivity()) .toBundle(); startActivity(intent, bundle); } diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/cards/CardExampleFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/cards/CardExampleFragment.java index a7b3f9771..4b2a44557 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/cards/CardExampleFragment.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/cards/CardExampleFragment.java @@ -14,21 +14,32 @@ package android.support.v17.leanback.supportleanbackshowcase.app.cards; +import android.content.Intent; import android.os.Bundle; +import android.os.Handler; import android.support.v17.leanback.app.BrowseFragment; -import android.support.v17.leanback.supportleanbackshowcase.utils.CardListRow; import android.support.v17.leanback.supportleanbackshowcase.R; +import android.support.v17.leanback.supportleanbackshowcase.app.details.DetailViewExampleActivity; +import android.support.v17.leanback.supportleanbackshowcase.app.details.DetailViewExampleFragment; import android.support.v17.leanback.supportleanbackshowcase.app.details.ShadowRowPresenterSelector; -import android.support.v17.leanback.supportleanbackshowcase.utils.Utils; +import android.support.v17.leanback.supportleanbackshowcase.cards.presenters.CardPresenterSelector; import android.support.v17.leanback.supportleanbackshowcase.models.Card; import android.support.v17.leanback.supportleanbackshowcase.models.CardRow; -import android.support.v17.leanback.supportleanbackshowcase.cards.presenters.CardPresenterSelector; +import android.support.v17.leanback.supportleanbackshowcase.utils.CardListRow; +import android.support.v17.leanback.supportleanbackshowcase.utils.Utils; import android.support.v17.leanback.widget.ArrayObjectAdapter; 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.OnItemViewClickedListener; +import android.support.v17.leanback.widget.Presenter; import android.support.v17.leanback.widget.PresenterSelector; +import android.support.v17.leanback.widget.Row; +import android.support.v17.leanback.widget.RowPresenter; import android.support.v17.leanback.widget.SearchOrbView; +import android.support.v4.app.ActivityOptionsCompat; import android.view.View; +import android.widget.ImageView; import android.widget.Toast; import com.google.gson.Gson; @@ -52,22 +63,50 @@ public class CardExampleFragment extends BrowseFragment { setHeadersTransitionOnBackEnabled(true); setSearchAffordanceColors( new SearchOrbView.Colors(getResources().getColor(R.color.search_color), - getResources().getColor(R.color.search_bright_color), - getResources().getColor(R.color.search_icon_color))); + getResources().getColor(R.color.search_bright_color), + getResources().getColor(R.color.search_icon_color))); setBrandColor(getResources().getColor(R.color.fastlane_background)); setTitle(getString(R.string.card_examples_title)); setOnSearchClickedListener(new View.OnClickListener() { - @Override public void onClick(View v) { + @Override + public void onClick(View v) { Toast.makeText(getActivity(), getString(R.string.implement_search), - Toast.LENGTH_LONG).show(); + Toast.LENGTH_LONG).show(); } }); + setOnItemViewClickedListener(new OnItemViewClickedListener() { + + @Override + public void onItemClicked(Presenter.ViewHolder viewHolder, Object item, RowPresenter.ViewHolder viewHolder1, Row row) { + if (!(item instanceof Card)) return; + if (!(viewHolder.view instanceof ImageCardView)) return; + + ImageView imageView = ((ImageCardView) viewHolder.view).getMainImageView(); + Bundle bundle = ActivityOptionsCompat.makeSceneTransitionAnimation(getActivity(), + imageView, DetailViewExampleFragment.TRANSITION_NAME).toBundle(); + Intent intent = new Intent(getActivity().getBaseContext(), + DetailViewExampleActivity.class); + Card card = (Card) item; + int imageResId = card.getLocalImageResourceId(getContext()); + intent.putExtra(DetailViewExampleFragment.EXTRA_CARD, imageResId); + startActivity(intent, bundle); + } + + }); + + prepareEntranceTransition(); } private void setupRowAdapter() { mRowsAdapter = new ArrayObjectAdapter(new ShadowRowPresenterSelector()); - createRows(); setAdapter(mRowsAdapter); + new Handler().postDelayed(new Runnable() { + @Override + public void run() { + createRows(); + startEntranceTransition(); + } + }, 500); } private void createRows() { diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/details/DetailViewExampleFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/details/DetailViewExampleFragment.java index 7f9e77a30..eed800ffd 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/details/DetailViewExampleFragment.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/details/DetailViewExampleFragment.java @@ -14,7 +14,10 @@ package android.support.v17.leanback.supportleanbackshowcase.app.details; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; import android.os.Bundle; +import android.os.Handler; import android.support.v17.leanback.app.DetailsFragment; import android.support.v17.leanback.supportleanbackshowcase.models.DetailedCard; import android.support.v17.leanback.supportleanbackshowcase.R; @@ -27,6 +30,7 @@ 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.FullWidthDetailsOverviewRowPresenter; +import android.support.v17.leanback.widget.FullWidthDetailsOverviewSharedElementHelper; import android.support.v17.leanback.widget.HeaderItem; import android.support.v17.leanback.widget.ListRow; import android.support.v17.leanback.widget.ListRowPresenter; @@ -47,11 +51,14 @@ import com.google.gson.Gson; public class DetailViewExampleFragment extends DetailsFragment implements OnItemViewClickedListener, OnItemViewSelectedListener { + public static final String TRANSITION_NAME = "t_for_transition"; + public static final String EXTRA_CARD = "card"; + private ArrayObjectAdapter mRowsAdapter; @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); setupUi(); setupEventListeners(); } @@ -85,6 +92,13 @@ public class DetailViewExampleFragment extends DetailsFragment implements OnItem return viewHolder; } }; + + FullWidthDetailsOverviewSharedElementHelper mHelper = new FullWidthDetailsOverviewSharedElementHelper(); + mHelper.setSharedElementEnterTransition(getActivity(), TRANSITION_NAME); + rowPresenter.setListener(mHelper); + rowPresenter.setParticipatingEntranceTransition(false); + prepareEntranceTransition(); + ListRowPresenter shadowDisabledRowPresenter = new ListRowPresenter(); shadowDisabledRowPresenter.setShadowEnabled(false); @@ -98,6 +112,11 @@ public class DetailViewExampleFragment extends DetailsFragment implements OnItem // Setup action and detail row. DetailsOverviewRow detailsOverview = new DetailsOverviewRow(data); int imageResId = data.getLocalImageResourceId(getActivity()); + + Bundle extras = getActivity().getIntent().getExtras(); + if (extras != null && extras.containsKey(EXTRA_CARD)) { + imageResId = extras.getInt(EXTRA_CARD, imageResId); + } detailsOverview.setImageDrawable(getResources().getDrawable(imageResId, null)); ArrayObjectAdapter actionAdapter = new ArrayObjectAdapter(); actionAdapter.add(new Action(1, getString(R.string.action_buy) + data.getPrice())); @@ -120,6 +139,12 @@ public class DetailViewExampleFragment extends DetailsFragment implements OnItem mRowsAdapter.add(new ListRow(header, listRowAdapter)); setAdapter(mRowsAdapter); + new Handler().postDelayed(new Runnable() { + @Override + public void run() { + startEntranceTransition(); + } + }, 500); } private void setupEventListeners() { diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/grid/GridExample.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/grid/GridExampleFragment.java similarity index 97% rename from samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/grid/GridExample.java rename to samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/grid/GridExampleFragment.java index e8cf3eba3..8002bf2c5 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/grid/GridExample.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/grid/GridExampleFragment.java @@ -30,7 +30,7 @@ import com.google.gson.Gson; /** * An example how to use leanback's {@link VerticalGridFragment}. */ -public class GridExample extends VerticalGridFragment { +public class GridExampleFragment extends VerticalGridFragment { private static final int COLUMNS = 4; private static final int ZOOM_FACTOR = FocusHighlight.ZOOM_FACTOR_MEDIUM; diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample1stStepFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample1stStepFragment.java index 0b0f6929c..e7808b113 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample1stStepFragment.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample1stStepFragment.java @@ -52,6 +52,7 @@ public class WizardExample1stStepFragment extends WizardExampleBaseStepFragment GuidedAction action = new GuidedAction.Builder() .id(ACTION_ID_BUY_HD) .title(getString(R.string.wizard_example_rent_hd)) + .editable(false) .description(mMovie.getPriceHd() + " " + getString(R.string.wizard_example_watch_hd)) .build(); @@ -59,6 +60,7 @@ public class WizardExample1stStepFragment extends WizardExampleBaseStepFragment action = new GuidedAction.Builder() .id(ACTION_ID_BUY_SD) .title(getString(R.string.wizard_example_rent_sd)) + .editable(false) .description(mMovie.getPriceSd() + " " + getString(R.string.wizard_example_watch_sd)) .build(); diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample2ndStepFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample2ndStepFragment.java index 7f3a83a39..8bbf5a455 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample2ndStepFragment.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample2ndStepFragment.java @@ -58,6 +58,7 @@ public class WizardExample2ndStepFragment extends WizardExampleBaseStepFragment getString(R.string.wizard_example_rental_period), mMovie.getBreadcrump(), null); return guidance; + } @Override @@ -68,12 +69,14 @@ public class WizardExample2ndStepFragment extends WizardExampleBaseStepFragment .id(ACTION_ID_CONFIRM) .title(getString(R.string.wizard_example_rent)) .description(rentHighDefinition ? mMovie.getPriceHd() : mMovie.getPriceSd()) + .editable(false) .build(); actions.add(action); action = new GuidedAction.Builder() .id(ACTION_ID_PAYMENT_METHOD) .title(getString(R.string.wizard_example_payment_method)) .description(getString(R.string.wizard_example_visa_balance)) + .editable(false) .build(); actions.add(action); } diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample4thStepFragment.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample4thStepFragment.java index 450311c24..5601fdac7 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample4thStepFragment.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/app/wizard/WizardExample4thStepFragment.java @@ -52,11 +52,13 @@ public class WizardExample4thStepFragment extends WizardExampleBaseStepFragment public void onCreateActions(@NonNull List actions, Bundle savedInstanceState) { GuidedAction action = new GuidedAction.Builder() .id(ACTION_ID_WATCH) + .editable(false) .title(getString(R.string.wizard_example_watch_now)) .build(); actions.add(action); action = new GuidedAction.Builder() .id(ACTION_ID_LATER) + .editable(false) .title(getString(R.string.wizard_example_later)) .build(); actions.add(action); diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/CharacterCardView.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/CharacterCardView.java index eeda4dae8..0486a4259 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/CharacterCardView.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/cards/CharacterCardView.java @@ -47,6 +47,7 @@ public class CharacterCardView extends BaseCardView { } }); setFocusable(true); + setBackground(null); } public void updateUi(Card card) { diff --git a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/utils/Utils.java b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/utils/Utils.java index 257aedbd0..4416cbe49 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/utils/Utils.java +++ b/samples/SupportLeanbackShowcase/app/src/main/java/android/support/v17/leanback/supportleanbackshowcase/utils/Utils.java @@ -16,16 +16,10 @@ package android.support.v17.leanback.supportleanbackshowcase.utils; import android.content.ContentResolver; import android.content.Context; -import android.graphics.drawable.Drawable; import android.net.Uri; -import android.widget.ImageView; - -import com.squareup.picasso.Picasso; -import com.squareup.picasso.RequestCreator; import java.io.IOException; import java.io.InputStream; -import java.net.URI; /** * A collection of utility methods, all static. @@ -55,37 +49,6 @@ public class Utils { } } - /** - * The method uses {@link Picasso} to fetch an image from a given url, resize it (if required) - * and display it inside an {@link ImageView}. - * - * @param context Context which is used to create a {@link Picasso} instance. - * @param uri The {@link URI} to fetch the image from. - * @param target The {@link ImageView} which shall display the image. - * @param resizeWidthInDp The target width of the image. Pass -1 if you don't want - * to resize the image. - * @param resizeHeightInDp The target height of the image. Pass -1 if you don't - * want to resize the image. - * @param centerCrop Centers and scales an image to fit the requested bounds. - * @param errorDrawable A drawable which will be shown in case the image could not be fetched - * from the server. - * @see {@link Picasso#with(Context)} - * @see {@link RequestCreator#resize(int, int)} - * @see {@link RequestCreator#centerCrop()} - * @see {@link RequestCreator#error(Drawable)} - */ - public static void loadImageFromUri(Context context, URI uri, ImageView target, - int resizeWidthInDp, int resizeHeightInDp, - boolean centerCrop, Drawable errorDrawable) { - if (uri == null) return; - RequestCreator builder = Picasso.with(context).load(uri.toString()); - if (resizeHeightInDp != -1 && resizeWidthInDp != -1) - builder.resize(Utils.convertDpToPixel(context, resizeWidthInDp), - Utils.convertDpToPixel(context, resizeHeightInDp)); - if (centerCrop) builder.centerCrop(); - builder.error(errorDrawable).into(target); - } - public static Uri getResourceUri(Context context, int resID) { return Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + context.getResources().getResourcePackageName(resID) + '/' + diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_cards_example.xml b/samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_cards_example.xml index cbcfe0539..903c52fd3 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_cards_example.xml +++ b/samples/SupportLeanbackShowcase/app/src/main/res/layout/activity_cards_example.xml @@ -17,6 +17,7 @@ \ No newline at end of file diff --git a/samples/SupportLeanbackShowcase/app/src/main/res/layout/character_card.xml b/samples/SupportLeanbackShowcase/app/src/main/res/layout/character_card.xml index 13f85845f..dee09a8e6 100644 --- a/samples/SupportLeanbackShowcase/app/src/main/res/layout/character_card.xml +++ b/samples/SupportLeanbackShowcase/app/src/main/res/layout/character_card.xml @@ -18,6 +18,7 @@ xmlns:lb="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" + lb:cardBackground="@null" lb:layout_viewType="main"> + + @@ -48,7 +51,7 @@ @color/settings_background -