Merge "Adding custom title view example in Showcase sample." into nyc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
c75fc99f05
@@ -34,7 +34,7 @@
|
||||
<activity
|
||||
android:name=".app.page.PageAndListRowActivity"
|
||||
android:exported="true"
|
||||
android:theme="@style/Theme.Example.LeanbackBrowse"/>
|
||||
android:theme="@style/Theme.Example.Leanback.CustomTitle"/>
|
||||
<activity
|
||||
android:name=".app.wizard.WizardExampleActivity"
|
||||
android:exported="true"
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
package android.support.v17.leanback.supportleanbackshowcase.app.page;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.support.v17.leanback.supportleanbackshowcase.R;
|
||||
import android.support.v17.leanback.widget.TitleViewAdapter;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
/**
|
||||
* Custom title view to be used in {@link android.support.v17.leanback.app.BrowseFragment}.
|
||||
*/
|
||||
public class CustomTitleView extends RelativeLayout implements TitleViewAdapter.Provider {
|
||||
private final TextView mTitleView;
|
||||
private final ImageView mBadgeView;
|
||||
|
||||
private final TitleViewAdapter mTitleViewAdapter = new TitleViewAdapter() {
|
||||
@Override
|
||||
public View getSearchAffordanceView() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTitle(CharSequence titleText) {
|
||||
CustomTitleView.this.setTitle(titleText);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBadgeDrawable(Drawable drawable) {
|
||||
CustomTitleView.this.setBadgeDrawable(drawable);
|
||||
}
|
||||
};
|
||||
|
||||
public CustomTitleView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public CustomTitleView(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public CustomTitleView(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
View root = LayoutInflater.from(context).inflate(R.layout.custom_titleview, this);
|
||||
mTitleView = (TextView) root.findViewById(R.id.title_tv);
|
||||
mBadgeView = (ImageView)root.findViewById(R.id.title_badge_iv);
|
||||
}
|
||||
|
||||
public void setTitle(CharSequence title) {
|
||||
if (title != null) {
|
||||
mTitleView.setText(title);
|
||||
mTitleView.setVisibility(View.VISIBLE);
|
||||
mBadgeView.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void setBadgeDrawable(Drawable drawable) {
|
||||
if (drawable != null) {
|
||||
mTitleView.setVisibility(View.GONE);
|
||||
mBadgeView.setImageDrawable(drawable);
|
||||
mBadgeView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public TitleViewAdapter getTitleViewAdapter() {
|
||||
return mTitleViewAdapter;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,205 @@
|
||||
package android.support.v17.leanback.supportleanbackshowcase.app.page;
|
||||
|
||||
import android.app.Fragment;
|
||||
import android.os.Bundle;
|
||||
import android.support.v17.leanback.app.BrowseFragment;
|
||||
import android.support.v17.leanback.supportleanbackshowcase.R;
|
||||
import android.support.v17.leanback.transition.TransitionHelper;
|
||||
import android.support.v17.leanback.widget.ObjectAdapter;
|
||||
import android.support.v17.leanback.widget.OnChildLaidOutListener;
|
||||
import android.support.v17.leanback.widget.OnItemViewClickedListener;
|
||||
import android.support.v17.leanback.widget.OnItemViewSelectedListener;
|
||||
import android.support.v17.leanback.widget.Presenter;
|
||||
import android.support.v17.leanback.widget.Row;
|
||||
import android.support.v17.leanback.widget.RowPresenter;
|
||||
import android.support.v17.leanback.widget.VerticalGridPresenter;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
/**
|
||||
* A fragment for rendering items in a vertical grids.
|
||||
*/
|
||||
public class GridFragment extends Fragment implements BrowseFragment.MainFragmentAdapterProvider {
|
||||
private static final String TAG = "VerticalGridFragment";
|
||||
private static boolean DEBUG = false;
|
||||
|
||||
private ObjectAdapter mAdapter;
|
||||
private VerticalGridPresenter mGridPresenter;
|
||||
private VerticalGridPresenter.ViewHolder mGridViewHolder;
|
||||
private OnItemViewSelectedListener mOnItemViewSelectedListener;
|
||||
private OnItemViewClickedListener mOnItemViewClickedListener;
|
||||
private Object mSceneAfterEntranceTransition;
|
||||
private int mSelectedPosition = -1;
|
||||
private BrowseFragment.MainFragmentAdapter mMainFragmentAdapter =
|
||||
new BrowseFragment.MainFragmentAdapter(this) {
|
||||
@Override
|
||||
public void setEntranceTransitionState(boolean state) {
|
||||
GridFragment.this.setEntranceTransitionState(state);
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Sets the grid presenter.
|
||||
*/
|
||||
public void setGridPresenter(VerticalGridPresenter gridPresenter) {
|
||||
if (gridPresenter == null) {
|
||||
throw new IllegalArgumentException("Grid presenter may not be null");
|
||||
}
|
||||
mGridPresenter = gridPresenter;
|
||||
mGridPresenter.setOnItemViewSelectedListener(mViewSelectedListener);
|
||||
if (mOnItemViewClickedListener != null) {
|
||||
mGridPresenter.setOnItemViewClickedListener(mOnItemViewClickedListener);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the grid presenter.
|
||||
*/
|
||||
public VerticalGridPresenter getGridPresenter() {
|
||||
return mGridPresenter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the object adapter for the fragment.
|
||||
*/
|
||||
public void setAdapter(ObjectAdapter adapter) {
|
||||
mAdapter = adapter;
|
||||
updateAdapter();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the object adapter.
|
||||
*/
|
||||
public ObjectAdapter getAdapter() {
|
||||
return mAdapter;
|
||||
}
|
||||
|
||||
final private OnItemViewSelectedListener mViewSelectedListener =
|
||||
new OnItemViewSelectedListener() {
|
||||
@Override
|
||||
public void onItemSelected(Presenter.ViewHolder itemViewHolder, Object item,
|
||||
RowPresenter.ViewHolder rowViewHolder, Row row) {
|
||||
int position = mGridViewHolder.getGridView().getSelectedPosition();
|
||||
if (DEBUG) Log.v(TAG, "grid selected position " + position);
|
||||
gridOnItemSelected(position);
|
||||
if (mOnItemViewSelectedListener != null) {
|
||||
mOnItemViewSelectedListener.onItemSelected(itemViewHolder, item,
|
||||
rowViewHolder, row);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
final private OnChildLaidOutListener mChildLaidOutListener =
|
||||
new OnChildLaidOutListener() {
|
||||
@Override
|
||||
public void onChildLaidOut(ViewGroup parent, View view, int position, long id) {
|
||||
if (position == 0) {
|
||||
showOrHideTitle();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets an item selection listener.
|
||||
*/
|
||||
public void setOnItemViewSelectedListener(OnItemViewSelectedListener listener) {
|
||||
mOnItemViewSelectedListener = listener;
|
||||
}
|
||||
|
||||
private void gridOnItemSelected(int position) {
|
||||
if (position != mSelectedPosition) {
|
||||
mSelectedPosition = position;
|
||||
showOrHideTitle();
|
||||
}
|
||||
}
|
||||
|
||||
private void showOrHideTitle() {
|
||||
if (mGridViewHolder.getGridView().findViewHolderForAdapterPosition(mSelectedPosition)
|
||||
== null) {
|
||||
return;
|
||||
}
|
||||
if (!mGridViewHolder.getGridView().hasPreviousViewInSameRow(mSelectedPosition)) {
|
||||
mMainFragmentAdapter.getFragmentHost().showTitleView(true);
|
||||
} else {
|
||||
mMainFragmentAdapter.getFragmentHost().showTitleView(false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an item clicked listener.
|
||||
*/
|
||||
public void setOnItemViewClickedListener(OnItemViewClickedListener listener) {
|
||||
mOnItemViewClickedListener = listener;
|
||||
if (mGridPresenter != null) {
|
||||
mGridPresenter.setOnItemViewClickedListener(mOnItemViewClickedListener);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the item clicked listener.
|
||||
*/
|
||||
public OnItemViewClickedListener getOnItemViewClickedListener() {
|
||||
return mOnItemViewClickedListener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
return inflater.inflate(R.layout.grid_fragment, container, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
ViewGroup gridDock = (ViewGroup) view.findViewById(R.id.browse_grid_dock);
|
||||
mGridViewHolder = mGridPresenter.onCreateViewHolder(gridDock);
|
||||
gridDock.addView(mGridViewHolder.view);
|
||||
mGridViewHolder.getGridView().setOnChildLaidOutListener(mChildLaidOutListener);
|
||||
|
||||
mSceneAfterEntranceTransition = TransitionHelper.createScene(gridDock, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
setEntranceTransitionState(true);
|
||||
}
|
||||
});
|
||||
|
||||
getMainFragmentAdapter().getFragmentHost().notifyViewCreated(mMainFragmentAdapter);
|
||||
updateAdapter();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
mGridViewHolder = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BrowseFragment.MainFragmentAdapter getMainFragmentAdapter() {
|
||||
return mMainFragmentAdapter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the selected item position.
|
||||
*/
|
||||
public void setSelectedPosition(int position) {
|
||||
mSelectedPosition = position;
|
||||
if(mGridViewHolder != null && mGridViewHolder.getGridView().getAdapter() != null) {
|
||||
mGridViewHolder.getGridView().setSelectedPositionSmooth(position);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateAdapter() {
|
||||
if (mGridViewHolder != null) {
|
||||
mGridPresenter.onBindViewHolder(mGridViewHolder, mAdapter);
|
||||
if (mSelectedPosition != -1) {
|
||||
mGridViewHolder.getGridView().setSelectedPosition(mSelectedPosition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void setEntranceTransitionState(boolean afterTransition) {
|
||||
mGridPresenter.setEntranceTransitionState(mGridViewHolder, afterTransition);
|
||||
}
|
||||
}
|
||||
@@ -7,11 +7,9 @@ import android.os.Handler;
|
||||
import android.support.v17.leanback.app.BackgroundManager;
|
||||
import android.support.v17.leanback.app.BrowseFragment;
|
||||
import android.support.v17.leanback.app.RowsFragment;
|
||||
import android.support.v17.leanback.app.VerticalGridFragment;
|
||||
import android.support.v17.leanback.supportleanbackshowcase.R;
|
||||
import android.support.v17.leanback.supportleanbackshowcase.app.details.ShadowRowPresenterSelector;
|
||||
import android.support.v17.leanback.supportleanbackshowcase.cards.presenters.CardPresenterSelector;
|
||||
import android.support.v17.leanback.supportleanbackshowcase.cards.presenters.IconCardPresenter;
|
||||
import android.support.v17.leanback.supportleanbackshowcase.models.Card;
|
||||
import android.support.v17.leanback.supportleanbackshowcase.models.CardRow;
|
||||
import android.support.v17.leanback.supportleanbackshowcase.utils.CardListRow;
|
||||
@@ -22,7 +20,6 @@ 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.OnItemViewClickedListener;
|
||||
import android.support.v17.leanback.widget.OnItemViewSelectedListener;
|
||||
import android.support.v17.leanback.widget.PageRow;
|
||||
import android.support.v17.leanback.widget.Presenter;
|
||||
import android.support.v17.leanback.widget.PresenterSelector;
|
||||
@@ -55,9 +52,6 @@ public class PageAndListRowFragment extends BrowseFragment {
|
||||
|
||||
private ArrayObjectAdapter mRowsAdapter;
|
||||
|
||||
public PageAndListRowFragment() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
@@ -73,9 +67,7 @@ public class PageAndListRowFragment extends BrowseFragment {
|
||||
setHeadersState(HEADERS_ENABLED);
|
||||
setHeadersTransitionOnBackEnabled(true);
|
||||
setBrandColor(getResources().getColor(R.color.fastlane_background));
|
||||
setTitle(getString(R.string.page_list_row_title));
|
||||
setBadgeDrawable(getActivity().getResources().getDrawable(
|
||||
R.drawable.abc_ab_share_pack_mtrl_alpha));
|
||||
setTitle("Title goes here");
|
||||
setOnSearchClickedListener(new View.OnClickListener() {
|
||||
|
||||
@Override
|
||||
@@ -132,7 +124,7 @@ public class PageAndListRowFragment extends BrowseFragment {
|
||||
Row row = (Row)rowObj;
|
||||
mBackgroundManager.setDrawable(null);
|
||||
if (row.getHeaderItem().getId() == HEADER_ID_1) {
|
||||
return new SampleFragmentA(mBackgroundManager);
|
||||
return new SampleFragmentA();
|
||||
} else if (row.getHeaderItem().getId() == HEADER_ID_2) {
|
||||
return new SampleFragmentB();
|
||||
} else if (row.getHeaderItem().getId() == HEADER_ID_3) {
|
||||
@@ -155,26 +147,20 @@ public class PageAndListRowFragment extends BrowseFragment {
|
||||
/**
|
||||
* Simple page fragment implementation.
|
||||
*/
|
||||
public static class SampleFragmentA extends VerticalGridFragment
|
||||
implements MainFragmentAdapterProvider {
|
||||
|
||||
public static class SampleFragmentA extends GridFragment {
|
||||
private static final int COLUMNS = 4;
|
||||
private final MainFragmentAdapter mMainFragmentAdapter =
|
||||
new PageAndListRowFragment.PageFragmentAdapterImpl(this);
|
||||
private final int ZOOM_FACTOR = FocusHighlight.ZOOM_FACTOR_SMALL;
|
||||
private final BackgroundManager mBackgroundManager;
|
||||
private ArrayObjectAdapter mAdapter;
|
||||
|
||||
public SampleFragmentA(BackgroundManager backgroundManager) {
|
||||
this.mBackgroundManager = backgroundManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setupAdapter();
|
||||
loadData();
|
||||
getMainFragmentAdapter().getFragmentHost().notifyDataReady(getMainFragmentAdapter());
|
||||
}
|
||||
|
||||
|
||||
private void setupAdapter() {
|
||||
VerticalGridPresenter presenter = new VerticalGridPresenter(ZOOM_FACTOR);
|
||||
presenter.setNumberOfColumns(COLUMNS);
|
||||
@@ -184,41 +170,19 @@ public class PageAndListRowFragment extends BrowseFragment {
|
||||
mAdapter = new ArrayObjectAdapter(cardPresenter);
|
||||
setAdapter(mAdapter);
|
||||
|
||||
setOnItemViewSelectedListener(new OnItemViewSelectedListener() {
|
||||
setOnItemViewClickedListener(new OnItemViewClickedListener() {
|
||||
@Override
|
||||
public void onItemSelected(
|
||||
public void onItemClicked(
|
||||
Presenter.ViewHolder itemViewHolder,
|
||||
Object item,
|
||||
RowPresenter.ViewHolder rowViewHolder,
|
||||
Row row) {
|
||||
|
||||
Card card = (Card)item;
|
||||
if(card.getLocalImageResourceName() != null) {
|
||||
int resourceId = getActivity().getResources().getIdentifier(
|
||||
card.getLocalImageResourceName(),
|
||||
"drawable",
|
||||
getActivity().getPackageName());
|
||||
|
||||
mBackgroundManager.setDrawable(getResources().getDrawable(resourceId));
|
||||
}
|
||||
Toast.makeText(getActivity(),
|
||||
"Clicked on "+card.getTitle(),
|
||||
Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
|
||||
prepareEntranceTransition();
|
||||
|
||||
new Handler().postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
loadData();
|
||||
startEntranceTransition();
|
||||
}
|
||||
}, 200);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
getMainFragmentAdapter().getFragmentHost().notifyViewCreated(mMainFragmentAdapter);
|
||||
}
|
||||
|
||||
private void loadData() {
|
||||
@@ -227,17 +191,6 @@ public class PageAndListRowFragment extends BrowseFragment {
|
||||
CardRow cardRow = new Gson().fromJson(json, CardRow.class);
|
||||
mAdapter.addAll(0, cardRow.getCards());
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(
|
||||
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
return super.onCreateView(inflater, container, savedInstanceState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MainFragmentAdapter getMainFragmentAdapter() {
|
||||
return mMainFragmentAdapter;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -263,33 +216,28 @@ public class PageAndListRowFragment extends BrowseFragment {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onAttach(Activity activity) {
|
||||
super.onAttach(activity);
|
||||
new Handler().postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
createRows();
|
||||
}
|
||||
}, 200);
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
createRows();
|
||||
getMainFragmentAdapter().getFragmentHost().notifyDataReady(getMainFragmentAdapter());
|
||||
}
|
||||
|
||||
private void createRows() {
|
||||
if (isAdded()) {
|
||||
String json = Utils.inputStreamToString(getResources().openRawResource(
|
||||
R.raw.cards_example));
|
||||
R.raw.page_row_example));
|
||||
CardRow[] rows = new Gson().fromJson(json, CardRow[].class);
|
||||
for (CardRow row : rows) {
|
||||
mRowsAdapter.add(createCardRow(row));
|
||||
if (row.getType() == CardRow.TYPE_DEFAULT) {
|
||||
mRowsAdapter.add(createCardRow(row));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ListRow createCardRow(CardRow cardRow) {
|
||||
private Row createCardRow(CardRow cardRow) {
|
||||
PresenterSelector presenterSelector = new CardPresenterSelector(getActivity());
|
||||
ArrayObjectAdapter adapter = new ArrayObjectAdapter(presenterSelector);
|
||||
for(Card card : cardRow.getCards()) {
|
||||
for (Card card : cardRow.getCards()) {
|
||||
adapter.add(card);
|
||||
}
|
||||
|
||||
@@ -325,6 +273,8 @@ public class PageAndListRowFragment extends BrowseFragment {
|
||||
R.raw.icon_example));
|
||||
CardRow cardRow = new Gson().fromJson(json, CardRow.class);
|
||||
mRowsAdapter.add(createCardRow(cardRow));
|
||||
getMainFragmentAdapter().getFragmentHost().notifyDataReady(
|
||||
getMainFragmentAdapter());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -368,6 +318,7 @@ public class PageAndListRowFragment extends BrowseFragment {
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
mWebview.loadUrl("https://www.google.com/policies/terms");
|
||||
getMainFragmentAdapter().getFragmentHost().notifyDataReady(getMainFragmentAdapter());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<merge xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<!--<android.support.v17.leanback.widget.SearchOrbView-->
|
||||
<!--android:id="@+id/search_orb"-->
|
||||
<!--android:layout_height="wrap_content"-->
|
||||
<!--android:layout_width="wrap_content"-->
|
||||
<!--android:transitionGroup="true"-->
|
||||
<!--android:layout_gravity="center_vertical|start"-->
|
||||
<!--android:layout_marginStart="56dp" />-->
|
||||
|
||||
<AnalogClock
|
||||
android:id="@+id/clock"
|
||||
android:layout_width="80dp"
|
||||
android:layout_height="80dp"
|
||||
android:padding="6dp"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_marginEnd="24dp" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/title_badge_iv"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="224dp"
|
||||
android:adjustViewBounds="true"
|
||||
android:layout_gravity="center_vertical|end"
|
||||
android:layout_toStartOf="@id/clock"
|
||||
android:src="@null"
|
||||
android:layout_centerVertical="true"
|
||||
android:visibility="gone" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title_tv"
|
||||
android:textAppearance="@android:style/TextAppearance.Large"
|
||||
android:visibility="gone"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="24dp"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_toStartOf="@id/clock" />
|
||||
|
||||
</merge>
|
||||
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/browse_dummy"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" >
|
||||
|
||||
<android.support.v17.leanback.widget.BrowseFrameLayout
|
||||
android:id="@+id/grid_frame"
|
||||
android:focusable="true"
|
||||
android:focusableInTouchMode="true"
|
||||
android:descendantFocusability="afterDescendants"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" >
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/browse_grid_dock"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
</android.support.v17.leanback.widget.BrowseFrameLayout>
|
||||
</FrameLayout>
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<android.support.v17.leanback.supportleanbackshowcase.app.page.CustomTitleView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/browse_title_group"
|
||||
android:padding="16dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
@@ -0,0 +1,515 @@
|
||||
[
|
||||
{
|
||||
"title": "One Line Title",
|
||||
"cards": [
|
||||
{
|
||||
"type": "MOVIE",
|
||||
"title": "Deep Into The Deep Sleep",
|
||||
"description": "$3.99",
|
||||
"localImageResource": "card_image_movie_01"
|
||||
},
|
||||
{
|
||||
"type": "MOVIE",
|
||||
"title": "We",
|
||||
"description": "$3.99",
|
||||
"localImageResource": "card_image_movie_02"
|
||||
},
|
||||
{
|
||||
"type": "MOVIE",
|
||||
"title": "The Fairy Story Of A Legend",
|
||||
"description": "$3.99",
|
||||
"localImageResource": "card_image_movie_03"
|
||||
},
|
||||
{
|
||||
"type": "MOVIE",
|
||||
"title": "Cursed",
|
||||
"description": "$3.99",
|
||||
"localImageResource": "card_image_movie_04"
|
||||
},
|
||||
{
|
||||
"type": "MOVIE",
|
||||
"title": "My Crazy One",
|
||||
"description": "$3.99",
|
||||
"localImageResource": "card_image_movie_05"
|
||||
},
|
||||
{
|
||||
"type": "MOVIE",
|
||||
"title": "Gone",
|
||||
"description": "$3.99",
|
||||
"localImageResource": "card_image_movie_06"
|
||||
},
|
||||
{
|
||||
"type": "MOVIE",
|
||||
"title": "A Cold Night To Stay",
|
||||
"description": "$3.99",
|
||||
"localImageResource": "card_image_movie_07"
|
||||
},
|
||||
{
|
||||
"type": "MOVIE",
|
||||
"title": "The Silence",
|
||||
"description": "$3.99",
|
||||
"localImageResource": "card_image_movie_08"
|
||||
},
|
||||
{
|
||||
"type": "MOVIE",
|
||||
"title": "Hear The Roar",
|
||||
"description": "$3.99",
|
||||
"localImageResource": "card_image_movie_09"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "Two Line Title",
|
||||
"cards": [
|
||||
{
|
||||
"type": "MOVIE_BASE",
|
||||
"title": "Deep Into The Deep Sleep",
|
||||
"description": "$3.99",
|
||||
"localImageResource": "card_image_movie_01"
|
||||
},
|
||||
{
|
||||
"type": "MOVIE_BASE",
|
||||
"title": "We",
|
||||
"description": "$3.99",
|
||||
"localImageResource": "card_image_movie_02"
|
||||
},
|
||||
{
|
||||
"type": "MOVIE_BASE",
|
||||
"title": "The Fairy Story Of A Legend",
|
||||
"description": "$3.99",
|
||||
"localImageResource": "card_image_movie_03"
|
||||
},
|
||||
{
|
||||
"type": "MOVIE_BASE",
|
||||
"title": "Cursed",
|
||||
"description": "$3.99",
|
||||
"localImageResource": "card_image_movie_04"
|
||||
},
|
||||
{
|
||||
"type": "MOVIE_BASE",
|
||||
"title": "My Crazy One",
|
||||
"description": "$3.99",
|
||||
"localImageResource": "card_image_movie_05"
|
||||
},
|
||||
{
|
||||
"type": "MOVIE_BASE",
|
||||
"title": "Gone",
|
||||
"description": "$3.99",
|
||||
"localImageResource": "card_image_movie_06"
|
||||
},
|
||||
{
|
||||
"type": "MOVIE_BASE",
|
||||
"title": "A Cold Night To Stay",
|
||||
"description": "$3.99",
|
||||
"localImageResource": "card_image_movie_07"
|
||||
},
|
||||
{
|
||||
"type": "MOVIE_BASE",
|
||||
"title": "The Silence",
|
||||
"description": "$3.99",
|
||||
"localImageResource": "card_image_movie_08"
|
||||
},
|
||||
{
|
||||
"type": "MOVIE_BASE",
|
||||
"title": "Hear The Roar",
|
||||
"description": "$3.99",
|
||||
"localImageResource": "card_image_movie_09"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "Two Line Title + Icon",
|
||||
"cards": [
|
||||
{
|
||||
"type": "MOVIE_COMPLETE",
|
||||
"description": "$3.99",
|
||||
"title": "Deep Into The Deep Sleep",
|
||||
"footerIconLocalImageResource": "stars_red",
|
||||
"localImageResource": "card_image_movie_01"
|
||||
},
|
||||
{
|
||||
"type": "MOVIE_COMPLETE",
|
||||
"title": "We",
|
||||
"description": "$3.99",
|
||||
"footerIconLocalImageResource": "stars_red",
|
||||
"localImageResource": "card_image_movie_02"
|
||||
},
|
||||
{
|
||||
"type": "MOVIE_COMPLETE",
|
||||
"title": "The Fairy",
|
||||
"description": "$3.99",
|
||||
"footerIconLocalImageResource": "stars_red",
|
||||
"localImageResource": "card_image_movie_03"
|
||||
},
|
||||
{
|
||||
"type": "MOVIE_COMPLETE",
|
||||
"title": "Cursed",
|
||||
"description": "$3.99",
|
||||
"footerIconLocalImageResource": "stars_red",
|
||||
"localImageResource": "card_image_movie_04"
|
||||
},
|
||||
{
|
||||
"type": "MOVIE_COMPLETE",
|
||||
"title": "My Crazy One",
|
||||
"description": "$3.99",
|
||||
"footerIconLocalImageResource": "stars_red",
|
||||
"localImageResource": "card_image_movie_05"
|
||||
},
|
||||
{
|
||||
"type": "MOVIE_COMPLETE",
|
||||
"title": "Gone",
|
||||
"description": "$3.99",
|
||||
"footerIconLocalImageResource": "stars_red",
|
||||
"localImageResource": "card_image_movie_06"
|
||||
},
|
||||
{
|
||||
"type": "MOVIE_COMPLETE",
|
||||
"title": "A Cold Night To Stay",
|
||||
"description": "$3.99",
|
||||
"footerIconLocalImageResource": "stars_red",
|
||||
"localImageResource": "card_image_movie_07"
|
||||
},
|
||||
{
|
||||
"type": "MOVIE_COMPLETE",
|
||||
"description": "$3.99",
|
||||
"title": "The Silence",
|
||||
"footerIconLocalImageResource": "stars_red",
|
||||
"localImageResource": "card_image_movie_08"
|
||||
},
|
||||
{
|
||||
"type": "MOVIE_COMPLETE",
|
||||
"title": "Hear The Roar",
|
||||
"description": "$3.99",
|
||||
"footerIconLocalImageResource": "stars_red",
|
||||
"localImageResource": "card_image_movie_09"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "Title + Description",
|
||||
"cards": [
|
||||
{
|
||||
"type": "SQUARE_BIG",
|
||||
"title": "Blue in Green",
|
||||
"description": "Miles Davis",
|
||||
"footerColor": "#bf360C",
|
||||
"localImageResource": "card_image_music_02"
|
||||
},
|
||||
{
|
||||
"type": "SQUARE_BIG",
|
||||
"title": "Blue in Green",
|
||||
"description": "Miles Davis",
|
||||
"footerColor": "#b93221",
|
||||
"localImageResource": "card_image_music_03"
|
||||
},
|
||||
{
|
||||
"type": "SQUARE_BIG",
|
||||
"title": "Blue in Green",
|
||||
"description": "Miles Davis",
|
||||
"footerColor": "#311b92",
|
||||
"localImageResource": "card_image_music_04"
|
||||
},
|
||||
{
|
||||
"type": "SQUARE_BIG",
|
||||
"title": "Blue in Green",
|
||||
"description": "Miles Davis",
|
||||
"footerColor": "#33691e",
|
||||
"localImageResource": "card_image_music_05"
|
||||
},
|
||||
{
|
||||
"type": "SQUARE_BIG",
|
||||
"title": "Blue in Green",
|
||||
"description": "Miles Davis",
|
||||
"footerColor": "#37474f",
|
||||
"localImageResource": "card_image_music_06"
|
||||
},
|
||||
{
|
||||
"type": "SQUARE_BIG",
|
||||
"title": "Blue in Green",
|
||||
"description": "Miles Davis",
|
||||
"footerColor": "#3e2723",
|
||||
"localImageResource": "card_image_music_08"
|
||||
},
|
||||
{
|
||||
"type": "SQUARE_BIG",
|
||||
"title": "Blue in Green",
|
||||
"description": "Miles Davis",
|
||||
"footerColor": "#01579B",
|
||||
"localImageResource": "card_image_music_09"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "Title + Description + Icon",
|
||||
"cards": [
|
||||
{
|
||||
"type": "GAME",
|
||||
"title": "Crazy One",
|
||||
"description": "Purchased",
|
||||
"localImageResource": "game_crazy_one",
|
||||
"footerIconLocalImageResource": "ic_installed"
|
||||
},
|
||||
{
|
||||
"type": "GAME",
|
||||
"title": "Cursed",
|
||||
"description": "Purchased",
|
||||
"localImageResource": "game_cursed",
|
||||
"footerIconLocalImageResource": "ic_installed"
|
||||
},
|
||||
{
|
||||
"type": "GAME",
|
||||
"title": "fairy",
|
||||
"description": "Purchased",
|
||||
"localImageResource": "game_fairy",
|
||||
"footerIconLocalImageResource": "ic_installed"
|
||||
},
|
||||
{
|
||||
"type": "GAME",
|
||||
"title": "Hear The Roar",
|
||||
"description": "Purchased",
|
||||
"localImageResource": "game_hear_the_roar",
|
||||
"footerIconLocalImageResource": "ic_installed"
|
||||
},
|
||||
{
|
||||
"type": "GAME",
|
||||
"title": "Silence",
|
||||
"description": "Purchased",
|
||||
"localImageResource": "game_silence",
|
||||
"footerIconLocalImageResource": "ic_installed"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "Title + Description (Wide)",
|
||||
"cards": [
|
||||
{
|
||||
"type": "DEFAULT",
|
||||
"title": "Marseille sea food tour",
|
||||
"description": "9,089 views 3 years ago by ADELAIDE",
|
||||
"localImageResource": "coffee_and_tea_01"
|
||||
},
|
||||
{
|
||||
"type": "DEFAULT",
|
||||
"title": "Marseille sea food tour",
|
||||
"description": "9,089 views 3 years ago by ADELAIDE",
|
||||
"localImageResource": "coffee_and_tea_02"
|
||||
},
|
||||
{
|
||||
"type": "DEFAULT",
|
||||
"title": "Marseille sea food tour",
|
||||
"description": "9,089 views 3 years ago by ADELAIDE",
|
||||
"localImageResource": "coffee_and_tea_03"
|
||||
},
|
||||
{
|
||||
"type": "DEFAULT",
|
||||
"title": "Marseille sea food tour",
|
||||
"description": "9,089 views 3 years ago by ADELAIDE",
|
||||
"localImageResource": "coffee_and_tea_04"
|
||||
},
|
||||
{
|
||||
"type": "DEFAULT",
|
||||
"title": "Marseille sea food tour",
|
||||
"description": "9,089 views 3 years ago by ADELAIDE",
|
||||
"localImageResource": "coffee_and_tea_05"
|
||||
},
|
||||
{
|
||||
"type": "DEFAULT",
|
||||
"title": "Marseille sea food tour",
|
||||
"description": "9,089 views 3 years ago by ADELAIDE",
|
||||
"localImageResource": "coffee_and_tea_06"
|
||||
},
|
||||
{
|
||||
"type": "DEFAULT",
|
||||
"title": "Marseille sea food tour",
|
||||
"description": "9,089 views 3 years ago by ADELAIDE",
|
||||
"localImageResource": "coffee_and_tea_07"
|
||||
},
|
||||
{
|
||||
"type": "DEFAULT",
|
||||
"title": "Marseille sea food tour",
|
||||
"description": "9,089 views 3 years ago by ADELAIDE",
|
||||
"localImageResource": "coffee_and_tea_08"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "BaseCardView Info On The Right",
|
||||
"cards": [
|
||||
{
|
||||
"type": "SIDE_INFO",
|
||||
"title": "The Life Aquatic",
|
||||
"description": "Seu Jorge",
|
||||
"extraText": "Bacon ipsum dolor amet bresaola kevin tenderloin swine shoulder strip steak t-bone picanha turducken beef. Ribeye turkey t-bone pastrami meatball corned beef. Pork belly landjaeger short ribs ground round cupim, brisket ham tri-tip. Pig pork loin hamburger picanha ribeye, pork belly meatball chicken ham boudin sirloin corned beef frankfurter ham hock.",
|
||||
"localImageResource": "card_image_music_02"
|
||||
},
|
||||
{
|
||||
"type": "SIDE_INFO",
|
||||
"title": "The Life Aquatic",
|
||||
"description": "Seu Jorge",
|
||||
"extraText": "Bacon ipsum dolor amet bresaola kevin tenderloin swine shoulder strip steak t-bone picanha turducken beef. Ribeye turkey t-bone pastrami meatball corned beef. Pork belly landjaeger short ribs ground round cupim, brisket ham tri-tip. Pig pork loin hamburger picanha ribeye, pork belly meatball chicken ham boudin sirloin corned beef frankfurter ham hock.",
|
||||
"localImageResource": "card_image_music_03"
|
||||
},
|
||||
{
|
||||
"type": "SIDE_INFO",
|
||||
"title": "The Life Aquatic",
|
||||
"description": "Seu Jorge",
|
||||
"extraText": "Bacon ipsum dolor amet bresaola kevin tenderloin swine shoulder strip steak t-bone picanha turducken beef. Ribeye turkey t-bone pastrami meatball corned beef. Pork belly landjaeger short ribs ground round cupim, brisket ham tri-tip. Pig pork loin hamburger picanha ribeye, pork belly meatball chicken ham boudin sirloin corned beef frankfurter ham hock.",
|
||||
"localImageResource": "card_image_music_04"
|
||||
},
|
||||
{
|
||||
"type": "SIDE_INFO",
|
||||
"title": "The Life Aquatic",
|
||||
"description": "Seu Jorge",
|
||||
"extraText": "Bacon ipsum dolor amet bresaola kevin tenderloin swine shoulder strip steak t-bone picanha turducken beef. Ribeye turkey t-bone pastrami meatball corned beef. Pork belly landjaeger short ribs ground round cupim, brisket ham tri-tip. Pig pork loin hamburger picanha ribeye, pork belly meatball chicken ham boudin sirloin corned beef frankfurter ham hock.",
|
||||
"localImageResource": "card_image_music_05"
|
||||
},
|
||||
{
|
||||
"type": "SIDE_INFO",
|
||||
"title": "The Life Aquatic",
|
||||
"description": "Seu Jorge",
|
||||
"extraText": "Bacon ipsum dolor amet bresaola kevin tenderloin swine shoulder strip steak t-bone picanha turducken beef. Ribeye turkey t-bone pastrami meatball corned beef. Pork belly landjaeger short ribs ground round cupim, brisket ham tri-tip. Pig pork loin hamburger picanha ribeye, pork belly meatball chicken ham boudin sirloin corned beef frankfurter ham hock.",
|
||||
"localImageResource": "card_image_music_06"
|
||||
},
|
||||
{
|
||||
"type": "SIDE_INFO",
|
||||
"title": "The Life Aquatic",
|
||||
"description": "Seu Jorge",
|
||||
"extraText": "Bacon ipsum dolor amet bresaola kevin tenderloin swine shoulder strip steak t-bone picanha turducken beef. Ribeye turkey t-bone pastrami meatball corned beef. Pork belly landjaeger short ribs ground round cupim, brisket ham tri-tip. Pig pork loin hamburger picanha ribeye, pork belly meatball chicken ham boudin sirloin corned beef frankfurter ham hock.",
|
||||
"localImageResource": "card_image_music_07"
|
||||
},
|
||||
{
|
||||
"type": "SIDE_INFO",
|
||||
"title": "The Life Aquatic",
|
||||
"description": "Seu Jorge",
|
||||
"extraText": "Bacon ipsum dolor amet bresaola kevin tenderloin swine shoulder strip steak t-bone picanha turducken beef. Ribeye turkey t-bone pastrami meatball corned beef. Pork belly landjaeger short ribs ground round cupim, brisket ham tri-tip. Pig pork loin hamburger picanha ribeye, pork belly meatball chicken ham boudin sirloin corned beef frankfurter ham hock.",
|
||||
"localImageResource": "card_image_music_08"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "BaseCardView using TextView",
|
||||
"cards": [
|
||||
{
|
||||
"type": "TEXT",
|
||||
"title": "Jonathan Max",
|
||||
"extraText": "Bacon ipsum dolor amet bresaola kevin tenderloin swine shoulder strip steak t-bone picanha turducken beef. Ribeye turkey t-bone pastrami meatball corned beef. Pork belly landjaeger short ribs ground round cupim, brisket ham tri-tip. Pig pork loin hamburger picanha ribeye, pork belly meatball chicken ham boudin sirloin corned beef frankfurter ham hock.",
|
||||
"localImageResource": "face_01"
|
||||
},
|
||||
{
|
||||
"type": "TEXT",
|
||||
"title": "Jonathan Max",
|
||||
"extraText": "Bacon ipsum dolor amet bresaola kevin tenderloin swine shoulder strip steak t-bone picanha turducken beef. Ribeye turkey t-bone pastrami meatball corned beef. Pork belly landjaeger short ribs ground round cupim, brisket ham tri-tip. Pig pork loin hamburger picanha ribeye, pork belly meatball chicken ham boudin sirloin corned beef frankfurter ham hock.",
|
||||
"localImageResource": "face_02"
|
||||
},
|
||||
{
|
||||
"type": "TEXT",
|
||||
"title": "Jonathan Max",
|
||||
"extraText": "Bacon ipsum dolor amet bresaola kevin tenderloin swine shoulder strip steak t-bone picanha turducken beef. Ribeye turkey t-bone pastrami meatball corned beef. Pork belly landjaeger short ribs ground round cupim, brisket ham tri-tip. Pig pork loin hamburger picanha ribeye, pork belly meatball chicken ham boudin sirloin corned beef frankfurter ham hock.",
|
||||
"localImageResource": "face_03"
|
||||
},
|
||||
{
|
||||
"type": "TEXT",
|
||||
"title": "Jonathan Max",
|
||||
"extraText": "Bacon ipsum dolor amet bresaola kevin tenderloin swine shoulder strip steak t-bone picanha turducken beef. Ribeye turkey t-bone pastrami meatball corned beef. Pork belly landjaeger short ribs ground round cupim, brisket ham tri-tip. Pig pork loin hamburger picanha ribeye, pork belly meatball chicken ham boudin sirloin corned beef frankfurter ham hock.",
|
||||
"localImageResource": "face_04"
|
||||
},
|
||||
{
|
||||
"type": "TEXT",
|
||||
"title": "Jonathan Max",
|
||||
"extraText": "Bacon ipsum dolor amet bresaola kevin tenderloin swine shoulder strip steak t-bone picanha turducken beef. Ribeye turkey t-bone pastrami meatball corned beef. Pork belly landjaeger short ribs ground round cupim, brisket ham tri-tip. Pig pork loin hamburger picanha ribeye, pork belly meatball chicken ham boudin sirloin corned beef frankfurter ham hock.",
|
||||
"localImageResource": "face_05"
|
||||
},
|
||||
{
|
||||
"type": "TEXT",
|
||||
"title": "Jonathan Max",
|
||||
"extraText": "Bacon ipsum dolor amet bresaola kevin tenderloin swine shoulder strip steak t-bone picanha turducken beef. Ribeye turkey t-bone pastrami meatball corned beef. Pork belly landjaeger short ribs ground round cupim, brisket ham tri-tip. Pig pork loin hamburger picanha ribeye, pork belly meatball chicken ham boudin sirloin corned beef frankfurter ham hock.",
|
||||
"localImageResource": "face_06"
|
||||
},
|
||||
{
|
||||
"type": "TEXT",
|
||||
"title": "Jonathan Max",
|
||||
"extraText": "Bacon ipsum dolor amet bresaola kevin tenderloin swine shoulder strip steak t-bone picanha turducken beef. Ribeye turkey t-bone pastrami meatball corned beef. Pork belly landjaeger short ribs ground round cupim, brisket ham tri-tip. Pig pork loin hamburger picanha ribeye, pork belly meatball chicken ham boudin sirloin corned beef frankfurter ham hock.",
|
||||
"localImageResource": "face_07"
|
||||
},
|
||||
{
|
||||
"type": "TEXT",
|
||||
"title": "Jonathan Max",
|
||||
"extraText": "Bacon ipsum dolor amet bresaola kevin tenderloin swine shoulder strip steak t-bone picanha turducken beef. Ribeye turkey t-bone pastrami meatball corned beef. Pork belly landjaeger short ribs ground round cupim, brisket ham tri-tip. Pig pork loin hamburger picanha ribeye, pork belly meatball chicken ham boudin sirloin corned beef frankfurter ham hock.",
|
||||
"localImageResource": "face_08"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "ImageCardView Customize Style",
|
||||
"cards": [
|
||||
{
|
||||
"type": "SINGLE_LINE",
|
||||
"title": "Action & Adventure",
|
||||
"footerColor": "#dd004e",
|
||||
"localImageResource": "category_action"
|
||||
},
|
||||
{
|
||||
"type": "SINGLE_LINE",
|
||||
"title": "Animation",
|
||||
"footerColor": "#c51162",
|
||||
"localImageResource": "category_animation"
|
||||
},
|
||||
{
|
||||
"type": "SINGLE_LINE",
|
||||
"title": "Classics",
|
||||
"footerColor": "#9c27b0",
|
||||
"localImageResource": "category_classics"
|
||||
},
|
||||
{
|
||||
"type": "SINGLE_LINE",
|
||||
"title": "Comedy",
|
||||
"footerColor": "#cf4900",
|
||||
"localImageResource": "category_comedy"
|
||||
},
|
||||
{
|
||||
"type": "SINGLE_LINE",
|
||||
"title": "Crime",
|
||||
"footerColor": "#3f51b5",
|
||||
"localImageResource": "category_crime"
|
||||
},
|
||||
{
|
||||
"type": "SINGLE_LINE",
|
||||
"title": "Documentary",
|
||||
"footerColor": "#02639b",
|
||||
"localImageResource": "category_documentary"
|
||||
},
|
||||
{
|
||||
"type": "SINGLE_LINE",
|
||||
"title": "Drama",
|
||||
"footerColor": "#2a56c6",
|
||||
"localImageResource": "category_drama"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "ImageCardView with onFocusChange listener",
|
||||
"shadow": false,
|
||||
"cards": [
|
||||
{
|
||||
"type": "ICON",
|
||||
"title": "Settings",
|
||||
"localImageResource": "ic_settings_settings"
|
||||
},
|
||||
{
|
||||
"type": "ICON",
|
||||
"title": "WiFi",
|
||||
"localImageResource": "ic_settings_wifi_3_bar"
|
||||
},
|
||||
{
|
||||
"type": "ICON",
|
||||
"title": "Parental Control",
|
||||
"localImageResource": "ic_settings_parental_control"
|
||||
},
|
||||
{
|
||||
"type": "ICON",
|
||||
"title": "Time",
|
||||
"localImageResource": "ic_settings_time"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -34,6 +34,11 @@
|
||||
<item name="defaultSearchBrightColor">@color/search_bright_color</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Example.Leanback.CustomTitle" parent="Theme.Example.LeanbackBrowse">
|
||||
<item name="browseTitleViewLayout">@layout/titleview</item>
|
||||
<item name="browseRowsMarginTop">120dp</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Example.LeanbackVerticalGrid" parent="Theme.Leanback.VerticalGrid">
|
||||
<item name="android:windowBackground">@drawable/background_food</item>
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user