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
This commit is contained in:
@@ -41,10 +41,10 @@
|
||||
android:theme="@style/Theme.Example.LeanbackDialog"></activity>
|
||||
<activity
|
||||
android:name=".app.details.DetailViewExampleActivity"
|
||||
android:theme="@style/Theme.Example.LeanbackDetailView"></activity>
|
||||
android:theme="@style/Theme.Example.LeanbackDetails"></activity>
|
||||
<activity
|
||||
android:name=".app.cards.CardExampleActivity"
|
||||
android:theme="@style/Theme.Example.Leanback"></activity>
|
||||
android:theme="@style/Theme.Example.LeanbackBrowse"></activity>
|
||||
<activity
|
||||
android:name=".app.grid.GridExampleActivity"
|
||||
android:theme="@style/Theme.Example.Leanback"></activity>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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;
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -52,11 +52,13 @@ public class WizardExample4thStepFragment extends WizardExampleBaseStepFragment
|
||||
public void onCreateActions(@NonNull List<GuidedAction> 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);
|
||||
|
||||
@@ -47,6 +47,7 @@ public class CharacterCardView extends BaseCardView {
|
||||
}
|
||||
});
|
||||
setFocusable(true);
|
||||
setBackground(null);
|
||||
}
|
||||
|
||||
public void updateUi(Card card) {
|
||||
|
||||
@@ -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 <code>-1</code> if you don't want
|
||||
* to resize the image.
|
||||
* @param resizeHeightInDp The target height of the image. Pass <code>-1</code> 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) + '/' +
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:background="@color/card_examples_background"
|
||||
android:transitionGroup="false"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<fragment
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:background="@drawable/background_canyon"
|
||||
android:transitionGroup="false"
|
||||
android:layout_height="match_parent">
|
||||
<fragment
|
||||
android:id="@+id/detailsFragment"
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
<fragment
|
||||
android:id="@+id/cardsFragment"
|
||||
android:name="android.support.v17.leanback.supportleanbackshowcase.app.grid.GridExample"
|
||||
android:name="android.support.v17.leanback.supportleanbackshowcase.app.grid.GridExampleFragment"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"></fragment>
|
||||
</RelativeLayout>
|
||||
@@ -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">
|
||||
|
||||
<LinearLayout
|
||||
|
||||
@@ -155,7 +155,7 @@
|
||||
</style>
|
||||
|
||||
<style name="IconCardStyle" parent="DefaultCardStyle">
|
||||
<item name="android:background">@null</item>
|
||||
<item name="cardBackground">@null</item>
|
||||
<item name="android:layout_width">96dp</item>
|
||||
<item name="android:layout_height">wrap_content</item>
|
||||
<item name="lbImageCardViewTitleStyle">@style/IconCardTitleStyle</item>
|
||||
|
||||
@@ -32,6 +32,9 @@
|
||||
<item name="browseRowsMarginTop">275dp</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Example.LeanbackBrowse" parent="Theme.Leanback.Browse">
|
||||
</style>
|
||||
|
||||
<style name="Theme.Example.LeanbackWizard" parent="Theme.Leanback.GuidedStep">
|
||||
<item name="guidedActionsContainerStyle">@style/WizardActionsContainerStyle</item>
|
||||
</style>
|
||||
@@ -48,7 +51,7 @@
|
||||
<item name="android:colorPrimary">@color/settings_background</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Example.LeanbackDetailView" parent="Theme.Leanback">
|
||||
<style name="Theme.Example.LeanbackDetails" parent="Theme.Leanback.Details">
|
||||
<item name="android:colorPrimary">@color/detail_view_actionbar_background</item>
|
||||
</style>
|
||||
</resources>
|
||||
|
||||
Reference in New Issue
Block a user