ListRowPresenter.java revision cb04695965b44b6ff633a773426df286d3bfaad9
147520b68e50572a9775a662410c5aff8300c8784Craig Stout/* 247520b68e50572a9775a662410c5aff8300c8784Craig Stout * Copyright (C) 2014 The Android Open Source Project 347520b68e50572a9775a662410c5aff8300c8784Craig Stout * 447520b68e50572a9775a662410c5aff8300c8784Craig Stout * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 547520b68e50572a9775a662410c5aff8300c8784Craig Stout * in compliance with the License. You may obtain a copy of the License at 647520b68e50572a9775a662410c5aff8300c8784Craig Stout * 747520b68e50572a9775a662410c5aff8300c8784Craig Stout * http://www.apache.org/licenses/LICENSE-2.0 847520b68e50572a9775a662410c5aff8300c8784Craig Stout * 947520b68e50572a9775a662410c5aff8300c8784Craig Stout * Unless required by applicable law or agreed to in writing, software distributed under the License 1047520b68e50572a9775a662410c5aff8300c8784Craig Stout * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 1147520b68e50572a9775a662410c5aff8300c8784Craig Stout * or implied. See the License for the specific language governing permissions and limitations under 1247520b68e50572a9775a662410c5aff8300c8784Craig Stout * the License. 1347520b68e50572a9775a662410c5aff8300c8784Craig Stout */ 1447520b68e50572a9775a662410c5aff8300c8784Craig Stoutpackage android.support.v17.leanback.widget; 1547520b68e50572a9775a662410c5aff8300c8784Craig Stout 16892181367d658f347d00ea5e091aa31f086b2a20Dake Guimport android.content.Context; 179240e796bc63422c28f2707840bd99c48573279bDake Guimport android.content.res.TypedArray; 18892181367d658f347d00ea5e091aa31f086b2a20Dake Guimport android.support.v17.leanback.R; 19cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Guimport android.support.v17.leanback.graphics.ColorOverlayDimmer; 204cd4cce277571385f4d1a56d5348578c38368cbeCraig Stoutimport android.util.Log; 2147520b68e50572a9775a662410c5aff8300c8784Craig Stoutimport android.view.View; 2247520b68e50572a9775a662410c5aff8300c8784Craig Stoutimport android.view.ViewGroup; 23892181367d658f347d00ea5e091aa31f086b2a20Dake Guimport android.view.ViewGroup.LayoutParams; 2447520b68e50572a9775a662410c5aff8300c8784Craig Stout 25bb370eee93bfe84a6e14be0e8476f48c32e2dcb0Craig Stoutimport java.util.HashMap; 26bb370eee93bfe84a6e14be0e8476f48c32e2dcb0Craig Stout 2747520b68e50572a9775a662410c5aff8300c8784Craig Stout/** 287aaa6c6ef8807cc4ea4c4642716d6e30056bc4ebDake Gu * ListRowPresenter renders {@link ListRow} using a 29cb13a318e577e14461eb008071dddf762847de42Dake Gu * {@link HorizontalGridView} hosted in a {@link ListRowView}. 307aaa6c6ef8807cc4ea4c4642716d6e30056bc4ebDake Gu * 317aaa6c6ef8807cc4ea4c4642716d6e30056bc4ebDake Gu * <h3>Hover card</h3> 3247520b68e50572a9775a662410c5aff8300c8784Craig Stout * Optionally, {@link #setHoverCardPresenterSelector(PresenterSelector)} can be used to 3347520b68e50572a9775a662410c5aff8300c8784Craig Stout * display a view for the currently focused list item below the rendered 3447520b68e50572a9775a662410c5aff8300c8784Craig Stout * list. This view is known as a hover card. 357aaa6c6ef8807cc4ea4c4642716d6e30056bc4ebDake Gu * 367aaa6c6ef8807cc4ea4c4642716d6e30056bc4ebDake Gu * <h3>Selection animation</h3> 377aaa6c6ef8807cc4ea4c4642716d6e30056bc4ebDake Gu * ListRowPresenter disables {@link RowPresenter}'s default dimming effect and draw 387aaa6c6ef8807cc4ea4c4642716d6e30056bc4ebDake Gu * a dim overlay on top of each individual child items. Subclass may override and disable 397aaa6c6ef8807cc4ea4c4642716d6e30056bc4ebDake Gu * {@link #isUsingDefaultListSelectEffect()} and write its own dim effect in 407aaa6c6ef8807cc4ea4c4642716d6e30056bc4ebDake Gu * {@link #onSelectLevelChanged(RowPresenter.ViewHolder)}. 41dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu * 42dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu * <h3>Shadow</h3> 43dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu * ListRowPresenter applies a default shadow to child of each view. Call 44dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu * {@link #setShadowEnabled(boolean)} to disable shadow. Subclass may override and return 45dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu * false in {@link #isUsingDefaultShadow()} and replace with its own shadow implementation. 4647520b68e50572a9775a662410c5aff8300c8784Craig Stout */ 4747520b68e50572a9775a662410c5aff8300c8784Craig Stoutpublic class ListRowPresenter extends RowPresenter { 4847520b68e50572a9775a662410c5aff8300c8784Craig Stout 4947520b68e50572a9775a662410c5aff8300c8784Craig Stout private static final String TAG = "ListRowPresenter"; 5047520b68e50572a9775a662410c5aff8300c8784Craig Stout private static final boolean DEBUG = false; 5147520b68e50572a9775a662410c5aff8300c8784Craig Stout 52bb370eee93bfe84a6e14be0e8476f48c32e2dcb0Craig Stout private static final int DEFAULT_RECYCLED_POOL_SIZE = 24; 53bb370eee93bfe84a6e14be0e8476f48c32e2dcb0Craig Stout 5447520b68e50572a9775a662410c5aff8300c8784Craig Stout public static class ViewHolder extends RowPresenter.ViewHolder { 5547520b68e50572a9775a662410c5aff8300c8784Craig Stout final ListRowPresenter mListRowPresenter; 5647520b68e50572a9775a662410c5aff8300c8784Craig Stout final HorizontalGridView mGridView; 5771fddded48048acfa744ac352166770c91a1c2b1Dake Gu ItemBridgeAdapter mItemBridgeAdapter; 5847520b68e50572a9775a662410c5aff8300c8784Craig Stout final HorizontalHoverCardSwitcher mHoverCardViewSwitcher = new HorizontalHoverCardSwitcher(); 59e43e9266c4b7e4902fefb5d2a0cacca90a3d2681Dake Gu final int mPaddingTop; 60e43e9266c4b7e4902fefb5d2a0cacca90a3d2681Dake Gu final int mPaddingBottom; 61e43e9266c4b7e4902fefb5d2a0cacca90a3d2681Dake Gu final int mPaddingLeft; 62e43e9266c4b7e4902fefb5d2a0cacca90a3d2681Dake Gu final int mPaddingRight; 6347520b68e50572a9775a662410c5aff8300c8784Craig Stout 6447520b68e50572a9775a662410c5aff8300c8784Craig Stout public ViewHolder(View rootView, HorizontalGridView gridView, ListRowPresenter p) { 6547520b68e50572a9775a662410c5aff8300c8784Craig Stout super(rootView); 6647520b68e50572a9775a662410c5aff8300c8784Craig Stout mGridView = gridView; 6747520b68e50572a9775a662410c5aff8300c8784Craig Stout mListRowPresenter = p; 68e43e9266c4b7e4902fefb5d2a0cacca90a3d2681Dake Gu mPaddingTop = mGridView.getPaddingTop(); 69e43e9266c4b7e4902fefb5d2a0cacca90a3d2681Dake Gu mPaddingBottom = mGridView.getPaddingBottom(); 70e43e9266c4b7e4902fefb5d2a0cacca90a3d2681Dake Gu mPaddingLeft = mGridView.getPaddingLeft(); 71e43e9266c4b7e4902fefb5d2a0cacca90a3d2681Dake Gu mPaddingRight = mGridView.getPaddingRight(); 7247520b68e50572a9775a662410c5aff8300c8784Craig Stout } 7347520b68e50572a9775a662410c5aff8300c8784Craig Stout 7447520b68e50572a9775a662410c5aff8300c8784Craig Stout public final ListRowPresenter getListRowPresenter() { 7547520b68e50572a9775a662410c5aff8300c8784Craig Stout return mListRowPresenter; 7647520b68e50572a9775a662410c5aff8300c8784Craig Stout } 7747520b68e50572a9775a662410c5aff8300c8784Craig Stout 7847520b68e50572a9775a662410c5aff8300c8784Craig Stout public final HorizontalGridView getGridView() { 7947520b68e50572a9775a662410c5aff8300c8784Craig Stout return mGridView; 8047520b68e50572a9775a662410c5aff8300c8784Craig Stout } 819de682083d3da5b1127969ee1fd7b74561aa9acdCraig Stout 829de682083d3da5b1127969ee1fd7b74561aa9acdCraig Stout public final ItemBridgeAdapter getBridgeAdapter() { 839de682083d3da5b1127969ee1fd7b74561aa9acdCraig Stout return mItemBridgeAdapter; 849de682083d3da5b1127969ee1fd7b74561aa9acdCraig Stout } 8547520b68e50572a9775a662410c5aff8300c8784Craig Stout } 8647520b68e50572a9775a662410c5aff8300c8784Craig Stout 8771fddded48048acfa744ac352166770c91a1c2b1Dake Gu class ListRowPresenterItemBridgeAdapter extends ItemBridgeAdapter { 8871fddded48048acfa744ac352166770c91a1c2b1Dake Gu ListRowPresenter.ViewHolder mRowViewHolder; 8971fddded48048acfa744ac352166770c91a1c2b1Dake Gu 9071fddded48048acfa744ac352166770c91a1c2b1Dake Gu ListRowPresenterItemBridgeAdapter(ListRowPresenter.ViewHolder rowViewHolder) { 9171fddded48048acfa744ac352166770c91a1c2b1Dake Gu mRowViewHolder = rowViewHolder; 9271fddded48048acfa744ac352166770c91a1c2b1Dake Gu } 9371fddded48048acfa744ac352166770c91a1c2b1Dake Gu 9471fddded48048acfa744ac352166770c91a1c2b1Dake Gu @Override 9571fddded48048acfa744ac352166770c91a1c2b1Dake Gu public void onBind(final ItemBridgeAdapter.ViewHolder viewHolder) { 9671fddded48048acfa744ac352166770c91a1c2b1Dake Gu // Only when having an OnItemClickListner, we will attach the OnClickListener. 9771fddded48048acfa744ac352166770c91a1c2b1Dake Gu if (getOnItemClickedListener() != null || getOnItemViewClickedListener() != null) { 9871fddded48048acfa744ac352166770c91a1c2b1Dake Gu viewHolder.mHolder.view.setOnClickListener(new View.OnClickListener() { 9971fddded48048acfa744ac352166770c91a1c2b1Dake Gu @Override 10071fddded48048acfa744ac352166770c91a1c2b1Dake Gu public void onClick(View v) { 10171fddded48048acfa744ac352166770c91a1c2b1Dake Gu ItemBridgeAdapter.ViewHolder ibh = (ItemBridgeAdapter.ViewHolder) 10271fddded48048acfa744ac352166770c91a1c2b1Dake Gu mRowViewHolder.mGridView.getChildViewHolder(viewHolder.itemView); 10371fddded48048acfa744ac352166770c91a1c2b1Dake Gu if (getOnItemClickedListener() != null) { 10471fddded48048acfa744ac352166770c91a1c2b1Dake Gu getOnItemClickedListener().onItemClicked(ibh.mItem, 10571fddded48048acfa744ac352166770c91a1c2b1Dake Gu (ListRow) mRowViewHolder.mRow); 10671fddded48048acfa744ac352166770c91a1c2b1Dake Gu } 10771fddded48048acfa744ac352166770c91a1c2b1Dake Gu if (getOnItemViewClickedListener() != null) { 10871fddded48048acfa744ac352166770c91a1c2b1Dake Gu getOnItemViewClickedListener().onItemClicked(viewHolder.mHolder, 10971fddded48048acfa744ac352166770c91a1c2b1Dake Gu ibh.mItem, mRowViewHolder, (ListRow) mRowViewHolder.mRow); 11071fddded48048acfa744ac352166770c91a1c2b1Dake Gu } 11171fddded48048acfa744ac352166770c91a1c2b1Dake Gu } 11271fddded48048acfa744ac352166770c91a1c2b1Dake Gu }); 11371fddded48048acfa744ac352166770c91a1c2b1Dake Gu } 11471fddded48048acfa744ac352166770c91a1c2b1Dake Gu } 11571fddded48048acfa744ac352166770c91a1c2b1Dake Gu 11671fddded48048acfa744ac352166770c91a1c2b1Dake Gu @Override 11771fddded48048acfa744ac352166770c91a1c2b1Dake Gu public void onUnbind(ItemBridgeAdapter.ViewHolder viewHolder) { 11871fddded48048acfa744ac352166770c91a1c2b1Dake Gu if (getOnItemClickedListener() != null || getOnItemViewClickedListener() != null) { 11971fddded48048acfa744ac352166770c91a1c2b1Dake Gu viewHolder.mHolder.view.setOnClickListener(null); 12071fddded48048acfa744ac352166770c91a1c2b1Dake Gu } 12171fddded48048acfa744ac352166770c91a1c2b1Dake Gu } 12271fddded48048acfa744ac352166770c91a1c2b1Dake Gu 12371fddded48048acfa744ac352166770c91a1c2b1Dake Gu @Override 12471fddded48048acfa744ac352166770c91a1c2b1Dake Gu public void onAttachedToWindow(ItemBridgeAdapter.ViewHolder viewHolder) { 12571fddded48048acfa744ac352166770c91a1c2b1Dake Gu if (viewHolder.itemView instanceof ShadowOverlayContainer) { 12671fddded48048acfa744ac352166770c91a1c2b1Dake Gu int dimmedColor = mRowViewHolder.mColorDimmer.getPaint().getColor(); 12771fddded48048acfa744ac352166770c91a1c2b1Dake Gu ((ShadowOverlayContainer) viewHolder.itemView).setOverlayColor(dimmedColor); 12871fddded48048acfa744ac352166770c91a1c2b1Dake Gu } 12971fddded48048acfa744ac352166770c91a1c2b1Dake Gu mRowViewHolder.syncActivatedStatus(viewHolder.itemView); 13071fddded48048acfa744ac352166770c91a1c2b1Dake Gu } 13171fddded48048acfa744ac352166770c91a1c2b1Dake Gu 13271fddded48048acfa744ac352166770c91a1c2b1Dake Gu @Override 13371fddded48048acfa744ac352166770c91a1c2b1Dake Gu public void onAddPresenter(Presenter presenter, int type) { 13471fddded48048acfa744ac352166770c91a1c2b1Dake Gu mRowViewHolder.getGridView().getRecycledViewPool().setMaxRecycledViews( 13571fddded48048acfa744ac352166770c91a1c2b1Dake Gu type, getRecycledPoolSize(presenter)); 13671fddded48048acfa744ac352166770c91a1c2b1Dake Gu } 13771fddded48048acfa744ac352166770c91a1c2b1Dake Gu } 13871fddded48048acfa744ac352166770c91a1c2b1Dake Gu 139a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn private int mRowHeight; 140a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn private int mExpandedRowHeight; 14147520b68e50572a9775a662410c5aff8300c8784Craig Stout private PresenterSelector mHoverCardPresenterSelector; 142b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout private int mZoomFactor; 143892181367d658f347d00ea5e091aa31f086b2a20Dake Gu private boolean mShadowEnabled = true; 1449240e796bc63422c28f2707840bd99c48573279bDake Gu private int mBrowseRowsFadingEdgeLength = -1; 1454f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout private boolean mRoundedCornersEnabled = true; 146bb370eee93bfe84a6e14be0e8476f48c32e2dcb0Craig Stout private HashMap<Presenter, Integer> mRecycledPoolSize = new HashMap<Presenter, Integer>(); 147b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout 1484cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout private static int sSelectedRowTopPadding; 1494cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout private static int sExpandedSelectedRowTopPadding; 1504cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout private static int sExpandedRowNoHovercardBottomPadding; 1514cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout 152b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout /** 153b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout * Constructs a ListRowPresenter with defaults. 154739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout * Uses {@link FocusHighlight#ZOOM_FACTOR_MEDIUM} for focus zooming. 155b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout */ 156b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout public ListRowPresenter() { 157739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout this(FocusHighlight.ZOOM_FACTOR_MEDIUM); 158b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout } 159b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout 160b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout /** 161b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout * Constructs a ListRowPresenter with the given parameters. 162b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout * 163b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout * @param zoomFactor Controls the zoom factor used when an item view is focused. One of 164739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout * {@link FocusHighlight#ZOOM_FACTOR_NONE}, 165739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout * {@link FocusHighlight#ZOOM_FACTOR_SMALL}, 166575dc8a5a5c023aee0c0ec297a7d357685cf49e9Craig Stout * {@link FocusHighlight#ZOOM_FACTOR_XSMALL}, 167739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout * {@link FocusHighlight#ZOOM_FACTOR_MEDIUM}, 168739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout * {@link FocusHighlight#ZOOM_FACTOR_LARGE} 169b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout */ 170b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout public ListRowPresenter(int zoomFactor) { 171575dc8a5a5c023aee0c0ec297a7d357685cf49e9Craig Stout if (!FocusHighlightHelper.isValidZoomIndex(zoomFactor)) { 172575dc8a5a5c023aee0c0ec297a7d357685cf49e9Craig Stout throw new IllegalArgumentException("Unhandled zoom factor"); 173575dc8a5a5c023aee0c0ec297a7d357685cf49e9Craig Stout } 174b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout mZoomFactor = zoomFactor; 175b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout } 176b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout 177b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout /** 178f272f7533fcb5aba341e9ab2f4ff0421d668a8caCraig Stout * Sets the row height for rows created by this Presenter. Rows 179a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn * created before calling this method will not be updated. 180a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn * 181f272f7533fcb5aba341e9ab2f4ff0421d668a8caCraig Stout * @param rowHeight Row height in pixels, or WRAP_CONTENT, or 0 182f272f7533fcb5aba341e9ab2f4ff0421d668a8caCraig Stout * to use the default height. 183a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn */ 184a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn public void setRowHeight(int rowHeight) { 185a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn mRowHeight = rowHeight; 186a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn } 187a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn 188a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn /** 189f272f7533fcb5aba341e9ab2f4ff0421d668a8caCraig Stout * Returns the row height for list rows created by this Presenter. 190a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn */ 191a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn public int getRowHeight() { 192a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn return mRowHeight; 193a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn } 194a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn 195a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn /** 196f272f7533fcb5aba341e9ab2f4ff0421d668a8caCraig Stout * Sets the expanded row height for rows created by this Presenter. 197f272f7533fcb5aba341e9ab2f4ff0421d668a8caCraig Stout * If not set, expanded rows have the same height as unexpanded 198a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn * rows. 199a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn * 200f272f7533fcb5aba341e9ab2f4ff0421d668a8caCraig Stout * @param rowHeight The row height in to use when the row is expanded, 201f272f7533fcb5aba341e9ab2f4ff0421d668a8caCraig Stout * in pixels, or WRAP_CONTENT, or 0 to use the default. 202a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn */ 203a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn public void setExpandedRowHeight(int rowHeight) { 204a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn mExpandedRowHeight = rowHeight; 205a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn } 206a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn 207a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn /** 208f272f7533fcb5aba341e9ab2f4ff0421d668a8caCraig Stout * Returns the expanded row height for rows created by this Presenter. 209a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn */ 210a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn public int getExpandedRowHeight() { 211f272f7533fcb5aba341e9ab2f4ff0421d668a8caCraig Stout return mExpandedRowHeight != 0 ? mExpandedRowHeight : mRowHeight; 212a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn } 213a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn 214a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn /** 215b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout * Returns the zoom factor used for focus highlighting. 216b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout */ 217b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout public final int getZoomFactor() { 218b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout return mZoomFactor; 219b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout } 22047520b68e50572a9775a662410c5aff8300c8784Craig Stout 221892181367d658f347d00ea5e091aa31f086b2a20Dake Gu private ItemBridgeAdapter.Wrapper mCardWrapper = new ItemBridgeAdapter.Wrapper() { 222892181367d658f347d00ea5e091aa31f086b2a20Dake Gu @Override 223892181367d658f347d00ea5e091aa31f086b2a20Dake Gu public View createWrapper(View root) { 224dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu ShadowOverlayContainer wrapper = new ShadowOverlayContainer(root.getContext()); 225892181367d658f347d00ea5e091aa31f086b2a20Dake Gu wrapper.setLayoutParams( 226892181367d658f347d00ea5e091aa31f086b2a20Dake Gu new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); 2274f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout wrapper.initialize(needsDefaultShadow(), 2284f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout needsDefaultListSelectEffect(), 2294f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout areChildRoundedCornersEnabled()); 230892181367d658f347d00ea5e091aa31f086b2a20Dake Gu return wrapper; 231892181367d658f347d00ea5e091aa31f086b2a20Dake Gu } 232892181367d658f347d00ea5e091aa31f086b2a20Dake Gu @Override 233892181367d658f347d00ea5e091aa31f086b2a20Dake Gu public void wrap(View wrapper, View wrapped) { 234dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu ((ShadowOverlayContainer) wrapper).wrap(wrapped); 235892181367d658f347d00ea5e091aa31f086b2a20Dake Gu } 236892181367d658f347d00ea5e091aa31f086b2a20Dake Gu }; 237892181367d658f347d00ea5e091aa31f086b2a20Dake Gu 23847520b68e50572a9775a662410c5aff8300c8784Craig Stout @Override 23947520b68e50572a9775a662410c5aff8300c8784Craig Stout protected void initializeRowViewHolder(RowPresenter.ViewHolder holder) { 24047520b68e50572a9775a662410c5aff8300c8784Craig Stout super.initializeRowViewHolder(holder); 24147520b68e50572a9775a662410c5aff8300c8784Craig Stout final ViewHolder rowViewHolder = (ViewHolder) holder; 24271fddded48048acfa744ac352166770c91a1c2b1Dake Gu rowViewHolder.mItemBridgeAdapter = new ListRowPresenterItemBridgeAdapter(rowViewHolder); 2434f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout if (needsDefaultListSelectEffect() || needsDefaultShadow() 2444f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout || areChildRoundedCornersEnabled()) { 245892181367d658f347d00ea5e091aa31f086b2a20Dake Gu rowViewHolder.mItemBridgeAdapter.setWrapper(mCardWrapper); 246892181367d658f347d00ea5e091aa31f086b2a20Dake Gu } 247cb13a318e577e14461eb008071dddf762847de42Dake Gu if (needsDefaultListSelectEffect()) { 248dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu ShadowOverlayContainer.prepareParentForShadow(rowViewHolder.mGridView); 249cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu } 25046e7de54775fc37dc51041629c79249e6dae3242Dake Gu FocusHighlightHelper.setupBrowseItemFocusHighlight(rowViewHolder.mItemBridgeAdapter, 25146e7de54775fc37dc51041629c79249e6dae3242Dake Gu mZoomFactor, false); 2520fcad32410ad29031630bb9cc2da35d33a4aa906Dake Gu rowViewHolder.mGridView.setFocusDrawingOrderEnabled(!isUsingZOrder()); 25347520b68e50572a9775a662410c5aff8300c8784Craig Stout rowViewHolder.mGridView.setOnChildSelectedListener( 25447520b68e50572a9775a662410c5aff8300c8784Craig Stout new OnChildSelectedListener() { 25547520b68e50572a9775a662410c5aff8300c8784Craig Stout @Override 25647520b68e50572a9775a662410c5aff8300c8784Craig Stout public void onChildSelected(ViewGroup parent, View view, int position, long id) { 25747520b68e50572a9775a662410c5aff8300c8784Craig Stout selectChildView(rowViewHolder, view); 25847520b68e50572a9775a662410c5aff8300c8784Craig Stout } 25947520b68e50572a9775a662410c5aff8300c8784Craig Stout }); 26047520b68e50572a9775a662410c5aff8300c8784Craig Stout } 26147520b68e50572a9775a662410c5aff8300c8784Craig Stout 262cb13a318e577e14461eb008071dddf762847de42Dake Gu final boolean needsDefaultListSelectEffect() { 263cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu return isUsingDefaultListSelectEffect() && getSelectEffectEnabled(); 264cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu } 265cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu 26647520b68e50572a9775a662410c5aff8300c8784Craig Stout /** 267bb370eee93bfe84a6e14be0e8476f48c32e2dcb0Craig Stout * Sets the recycled pool size for the given presenter. 268bb370eee93bfe84a6e14be0e8476f48c32e2dcb0Craig Stout */ 269bb370eee93bfe84a6e14be0e8476f48c32e2dcb0Craig Stout public void setRecycledPoolSize(Presenter presenter, int size) { 270bb370eee93bfe84a6e14be0e8476f48c32e2dcb0Craig Stout mRecycledPoolSize.put(presenter, size); 271bb370eee93bfe84a6e14be0e8476f48c32e2dcb0Craig Stout } 272bb370eee93bfe84a6e14be0e8476f48c32e2dcb0Craig Stout 273bb370eee93bfe84a6e14be0e8476f48c32e2dcb0Craig Stout /** 274bb370eee93bfe84a6e14be0e8476f48c32e2dcb0Craig Stout * Returns the recycled pool size for the given presenter. 275bb370eee93bfe84a6e14be0e8476f48c32e2dcb0Craig Stout */ 276bb370eee93bfe84a6e14be0e8476f48c32e2dcb0Craig Stout public int getRecycledPoolSize(Presenter presenter) { 277bb370eee93bfe84a6e14be0e8476f48c32e2dcb0Craig Stout return mRecycledPoolSize.containsKey(presenter) ? mRecycledPoolSize.get(presenter) : 278bb370eee93bfe84a6e14be0e8476f48c32e2dcb0Craig Stout DEFAULT_RECYCLED_POOL_SIZE; 279bb370eee93bfe84a6e14be0e8476f48c32e2dcb0Craig Stout } 280bb370eee93bfe84a6e14be0e8476f48c32e2dcb0Craig Stout 281bb370eee93bfe84a6e14be0e8476f48c32e2dcb0Craig Stout /** 28247520b68e50572a9775a662410c5aff8300c8784Craig Stout * Set {@link PresenterSelector} used for showing a select object in a hover card. 28347520b68e50572a9775a662410c5aff8300c8784Craig Stout */ 28447520b68e50572a9775a662410c5aff8300c8784Craig Stout public final void setHoverCardPresenterSelector(PresenterSelector selector) { 28547520b68e50572a9775a662410c5aff8300c8784Craig Stout mHoverCardPresenterSelector = selector; 28647520b68e50572a9775a662410c5aff8300c8784Craig Stout } 28747520b68e50572a9775a662410c5aff8300c8784Craig Stout 28847520b68e50572a9775a662410c5aff8300c8784Craig Stout /** 28947520b68e50572a9775a662410c5aff8300c8784Craig Stout * Get {@link PresenterSelector} used for showing a select object in a hover card. 29047520b68e50572a9775a662410c5aff8300c8784Craig Stout */ 29147520b68e50572a9775a662410c5aff8300c8784Craig Stout public final PresenterSelector getHoverCardPresenterSelector() { 29247520b68e50572a9775a662410c5aff8300c8784Craig Stout return mHoverCardPresenterSelector; 29347520b68e50572a9775a662410c5aff8300c8784Craig Stout } 29447520b68e50572a9775a662410c5aff8300c8784Craig Stout 29547520b68e50572a9775a662410c5aff8300c8784Craig Stout /* 29647520b68e50572a9775a662410c5aff8300c8784Craig Stout * Perform operations when a child of horizontal grid view is selected. 29747520b68e50572a9775a662410c5aff8300c8784Craig Stout */ 29847520b68e50572a9775a662410c5aff8300c8784Craig Stout private void selectChildView(ViewHolder rowViewHolder, View view) { 29947520b68e50572a9775a662410c5aff8300c8784Craig Stout if (view != null) { 3003173fdc69a928880a271036570c235f874b86f65butterfield@google.com if (rowViewHolder.mExpanded && rowViewHolder.mSelected) { 3013173fdc69a928880a271036570c235f874b86f65butterfield@google.com ItemBridgeAdapter.ViewHolder ibh = (ItemBridgeAdapter.ViewHolder) 3023173fdc69a928880a271036570c235f874b86f65butterfield@google.com rowViewHolder.mGridView.getChildViewHolder(view); 3033173fdc69a928880a271036570c235f874b86f65butterfield@google.com 3043173fdc69a928880a271036570c235f874b86f65butterfield@google.com if (mHoverCardPresenterSelector != null) { 3053173fdc69a928880a271036570c235f874b86f65butterfield@google.com rowViewHolder.mHoverCardViewSwitcher.select(rowViewHolder.mGridView, view, 3063173fdc69a928880a271036570c235f874b86f65butterfield@google.com ibh.mItem); 3073173fdc69a928880a271036570c235f874b86f65butterfield@google.com } 3083173fdc69a928880a271036570c235f874b86f65butterfield@google.com if (getOnItemViewSelectedListener() != null) { 3093173fdc69a928880a271036570c235f874b86f65butterfield@google.com getOnItemViewSelectedListener().onItemSelected(ibh.mHolder, ibh.mItem, 3103173fdc69a928880a271036570c235f874b86f65butterfield@google.com rowViewHolder, rowViewHolder.mRow); 3113173fdc69a928880a271036570c235f874b86f65butterfield@google.com } 3123173fdc69a928880a271036570c235f874b86f65butterfield@google.com if (getOnItemSelectedListener() != null) { 3133173fdc69a928880a271036570c235f874b86f65butterfield@google.com getOnItemSelectedListener().onItemSelected(ibh.mItem, rowViewHolder.mRow); 3143173fdc69a928880a271036570c235f874b86f65butterfield@google.com } 3153173fdc69a928880a271036570c235f874b86f65butterfield@google.com } 3163173fdc69a928880a271036570c235f874b86f65butterfield@google.com } else { 31747520b68e50572a9775a662410c5aff8300c8784Craig Stout if (mHoverCardPresenterSelector != null) { 31847520b68e50572a9775a662410c5aff8300c8784Craig Stout rowViewHolder.mHoverCardViewSwitcher.unselect(); 31947520b68e50572a9775a662410c5aff8300c8784Craig Stout } 3209de363b8db05106b03d115c266859fe200d41db7Dake Gu if (getOnItemViewSelectedListener() != null) { 3219de363b8db05106b03d115c266859fe200d41db7Dake Gu getOnItemViewSelectedListener().onItemSelected(null, null, 3229de363b8db05106b03d115c266859fe200d41db7Dake Gu rowViewHolder, rowViewHolder.mRow); 3239de363b8db05106b03d115c266859fe200d41db7Dake Gu } 32447520b68e50572a9775a662410c5aff8300c8784Craig Stout if (getOnItemSelectedListener() != null) { 32547520b68e50572a9775a662410c5aff8300c8784Craig Stout getOnItemSelectedListener().onItemSelected(null, rowViewHolder.mRow); 32647520b68e50572a9775a662410c5aff8300c8784Craig Stout } 32747520b68e50572a9775a662410c5aff8300c8784Craig Stout } 32847520b68e50572a9775a662410c5aff8300c8784Craig Stout } 32947520b68e50572a9775a662410c5aff8300c8784Craig Stout 3304cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout private static void initStatics(Context context) { 3314cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout if (sSelectedRowTopPadding == 0) { 3324cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout sSelectedRowTopPadding = context.getResources().getDimensionPixelSize( 3334cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout R.dimen.lb_browse_selected_row_top_padding); 3344cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout sExpandedSelectedRowTopPadding = context.getResources().getDimensionPixelSize( 3354cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout R.dimen.lb_browse_expanded_selected_row_top_padding); 3364cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout sExpandedRowNoHovercardBottomPadding = context.getResources().getDimensionPixelSize( 3374cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout R.dimen.lb_browse_expanded_row_no_hovercard_bottom_padding); 3384cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout } 3394cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout } 3404cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout 3414cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout private int getSpaceUnderBaseline(ListRowPresenter.ViewHolder vh) { 3424cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout RowHeaderPresenter.ViewHolder headerViewHolder = vh.getHeaderViewHolder(); 3434cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout if (headerViewHolder != null) { 3444cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout if (getHeaderPresenter() != null) { 3454cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout return getHeaderPresenter().getSpaceUnderBaseline(headerViewHolder); 3464cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout } 3474cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout return headerViewHolder.view.getPaddingBottom(); 3484cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout } 3494cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout return 0; 3504cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout } 3514cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout 3524cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout private void setVerticalPadding(ListRowPresenter.ViewHolder vh) { 3534cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout int paddingTop, paddingBottom; 3543146269a82645438b55a41c679047e3be36e65dfCraig Stout // Note: sufficient bottom padding needed for card shadows. 3554cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout if (vh.isExpanded()) { 3564cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout int headerSpaceUnderBaseline = getSpaceUnderBaseline(vh); 3574cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout if (DEBUG) Log.v(TAG, "headerSpaceUnderBaseline " + headerSpaceUnderBaseline); 3584cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout paddingTop = (vh.isSelected() ? sExpandedSelectedRowTopPadding : vh.mPaddingTop) - 3594cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout headerSpaceUnderBaseline; 3604cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout paddingBottom = mHoverCardPresenterSelector == null ? 3614cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout sExpandedRowNoHovercardBottomPadding : vh.mPaddingBottom; 3624cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout } else if (vh.isSelected()) { 3633146269a82645438b55a41c679047e3be36e65dfCraig Stout paddingTop = sSelectedRowTopPadding - vh.mPaddingBottom; 3643146269a82645438b55a41c679047e3be36e65dfCraig Stout paddingBottom = sSelectedRowTopPadding; 3654cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout } else { 3663146269a82645438b55a41c679047e3be36e65dfCraig Stout paddingTop = 0; 3673146269a82645438b55a41c679047e3be36e65dfCraig Stout paddingBottom = vh.mPaddingBottom; 3684cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout } 3694cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout vh.getGridView().setPadding(vh.mPaddingLeft, paddingTop, vh.mPaddingRight, 3704cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout paddingBottom); 3714cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout } 3724cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout 37347520b68e50572a9775a662410c5aff8300c8784Craig Stout @Override 37447520b68e50572a9775a662410c5aff8300c8784Craig Stout protected RowPresenter.ViewHolder createRowViewHolder(ViewGroup parent) { 3754cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout initStatics(parent.getContext()); 376cb13a318e577e14461eb008071dddf762847de42Dake Gu ListRowView rowView = new ListRowView(parent.getContext()); 3779240e796bc63422c28f2707840bd99c48573279bDake Gu setupFadingEffect(rowView); 378f272f7533fcb5aba341e9ab2f4ff0421d668a8caCraig Stout if (mRowHeight != 0) { 379a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn rowView.getGridView().setRowHeight(mRowHeight); 380a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn } 38147520b68e50572a9775a662410c5aff8300c8784Craig Stout return new ViewHolder(rowView, rowView.getGridView(), this); 38247520b68e50572a9775a662410c5aff8300c8784Craig Stout } 38347520b68e50572a9775a662410c5aff8300c8784Craig Stout 384cb04695965b44b6ff633a773426df286d3bfaad9John Butterfield /** 385cb04695965b44b6ff633a773426df286d3bfaad9John Butterfield * Dispatch item selected event using current selected item in the {@link HorizontalGridView}. 386cb04695965b44b6ff633a773426df286d3bfaad9John Butterfield * The method should only be called from onRowViewSelected(). 387cb04695965b44b6ff633a773426df286d3bfaad9John Butterfield */ 388cb04695965b44b6ff633a773426df286d3bfaad9John Butterfield @Override 389cb04695965b44b6ff633a773426df286d3bfaad9John Butterfield protected void dispatchItemSelectedListener(RowPresenter.ViewHolder holder, boolean selected) { 390cb04695965b44b6ff633a773426df286d3bfaad9John Butterfield ViewHolder vh = (ViewHolder)holder; 391cb04695965b44b6ff633a773426df286d3bfaad9John Butterfield ItemBridgeAdapter.ViewHolder itemViewHolder = (ItemBridgeAdapter.ViewHolder) 392cb04695965b44b6ff633a773426df286d3bfaad9John Butterfield vh.mGridView.findViewHolderForPosition(vh.mGridView.getSelectedPosition()); 393cb04695965b44b6ff633a773426df286d3bfaad9John Butterfield if (itemViewHolder == null) { 394cb04695965b44b6ff633a773426df286d3bfaad9John Butterfield super.dispatchItemSelectedListener(holder, selected); 395cb04695965b44b6ff633a773426df286d3bfaad9John Butterfield return; 396cb04695965b44b6ff633a773426df286d3bfaad9John Butterfield } 397cb04695965b44b6ff633a773426df286d3bfaad9John Butterfield 398cb04695965b44b6ff633a773426df286d3bfaad9John Butterfield if (selected) { 399cb04695965b44b6ff633a773426df286d3bfaad9John Butterfield if (getOnItemViewSelectedListener() != null) { 400cb04695965b44b6ff633a773426df286d3bfaad9John Butterfield getOnItemViewSelectedListener().onItemSelected( 401cb04695965b44b6ff633a773426df286d3bfaad9John Butterfield itemViewHolder.getViewHolder(), itemViewHolder.mItem, vh, vh.getRow()); 402cb04695965b44b6ff633a773426df286d3bfaad9John Butterfield } 403cb04695965b44b6ff633a773426df286d3bfaad9John Butterfield if (getOnItemSelectedListener() != null) { 404cb04695965b44b6ff633a773426df286d3bfaad9John Butterfield getOnItemSelectedListener().onItemSelected(itemViewHolder.mItem, vh.getRow()); 405cb04695965b44b6ff633a773426df286d3bfaad9John Butterfield } 406cb04695965b44b6ff633a773426df286d3bfaad9John Butterfield } 407cb04695965b44b6ff633a773426df286d3bfaad9John Butterfield } 408cb04695965b44b6ff633a773426df286d3bfaad9John Butterfield 40947520b68e50572a9775a662410c5aff8300c8784Craig Stout @Override 41047520b68e50572a9775a662410c5aff8300c8784Craig Stout protected void onRowViewSelected(RowPresenter.ViewHolder holder, boolean selected) { 4112f97594742886d045ca1ce409ebc6e6e780452f6Dake Gu super.onRowViewSelected(holder, selected); 4124cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout ViewHolder vh = (ViewHolder) holder; 4134cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout setVerticalPadding(vh); 4144cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout updateFooterViewSwitcher(vh); 41547520b68e50572a9775a662410c5aff8300c8784Craig Stout } 41647520b68e50572a9775a662410c5aff8300c8784Craig Stout 41747520b68e50572a9775a662410c5aff8300c8784Craig Stout /* 41847520b68e50572a9775a662410c5aff8300c8784Craig Stout * Show or hide hover card when row selection or expanded state is changed. 41947520b68e50572a9775a662410c5aff8300c8784Craig Stout */ 42047520b68e50572a9775a662410c5aff8300c8784Craig Stout private void updateFooterViewSwitcher(ViewHolder vh) { 42147520b68e50572a9775a662410c5aff8300c8784Craig Stout if (vh.mExpanded && vh.mSelected) { 42247520b68e50572a9775a662410c5aff8300c8784Craig Stout if (mHoverCardPresenterSelector != null) { 42347520b68e50572a9775a662410c5aff8300c8784Craig Stout vh.mHoverCardViewSwitcher.init((ViewGroup) vh.view, 42447520b68e50572a9775a662410c5aff8300c8784Craig Stout mHoverCardPresenterSelector); 42547520b68e50572a9775a662410c5aff8300c8784Craig Stout } 42602e411c2c69d20aab138f1a162a24ea650eff7a1Dake Gu ItemBridgeAdapter.ViewHolder ibh = (ItemBridgeAdapter.ViewHolder) 42702e411c2c69d20aab138f1a162a24ea650eff7a1Dake Gu vh.mGridView.findViewHolderForPosition( 42802e411c2c69d20aab138f1a162a24ea650eff7a1Dake Gu vh.mGridView.getSelectedPosition()); 42902e411c2c69d20aab138f1a162a24ea650eff7a1Dake Gu selectChildView(vh, ibh == null ? null : ibh.itemView); 43047520b68e50572a9775a662410c5aff8300c8784Craig Stout } else { 43147520b68e50572a9775a662410c5aff8300c8784Craig Stout if (mHoverCardPresenterSelector != null) { 4322f97594742886d045ca1ce409ebc6e6e780452f6Dake Gu vh.mHoverCardViewSwitcher.unselect(); 43347520b68e50572a9775a662410c5aff8300c8784Craig Stout } 43447520b68e50572a9775a662410c5aff8300c8784Craig Stout } 43547520b68e50572a9775a662410c5aff8300c8784Craig Stout } 43647520b68e50572a9775a662410c5aff8300c8784Craig Stout 4379240e796bc63422c28f2707840bd99c48573279bDake Gu private void setupFadingEffect(ListRowView rowView) { 4389240e796bc63422c28f2707840bd99c48573279bDake Gu // content is completely faded at 1/2 padding of left, fading length is 1/2 of padding. 4399240e796bc63422c28f2707840bd99c48573279bDake Gu HorizontalGridView gridView = rowView.getGridView(); 4409240e796bc63422c28f2707840bd99c48573279bDake Gu if (mBrowseRowsFadingEdgeLength < 0) { 4419240e796bc63422c28f2707840bd99c48573279bDake Gu TypedArray ta = gridView.getContext() 4429240e796bc63422c28f2707840bd99c48573279bDake Gu .obtainStyledAttributes(R.styleable.LeanbackTheme); 4439240e796bc63422c28f2707840bd99c48573279bDake Gu mBrowseRowsFadingEdgeLength = (int) ta.getDimension( 4449240e796bc63422c28f2707840bd99c48573279bDake Gu R.styleable.LeanbackTheme_browseRowsFadingEdgeLength, 0); 4459240e796bc63422c28f2707840bd99c48573279bDake Gu ta.recycle(); 44647520b68e50572a9775a662410c5aff8300c8784Craig Stout } 4479240e796bc63422c28f2707840bd99c48573279bDake Gu gridView.setFadingLeftEdgeLength(mBrowseRowsFadingEdgeLength); 44847520b68e50572a9775a662410c5aff8300c8784Craig Stout } 44947520b68e50572a9775a662410c5aff8300c8784Craig Stout 45047520b68e50572a9775a662410c5aff8300c8784Craig Stout @Override 45147520b68e50572a9775a662410c5aff8300c8784Craig Stout protected void onRowViewExpanded(RowPresenter.ViewHolder holder, boolean expanded) { 45247520b68e50572a9775a662410c5aff8300c8784Craig Stout super.onRowViewExpanded(holder, expanded); 45347520b68e50572a9775a662410c5aff8300c8784Craig Stout ViewHolder vh = (ViewHolder) holder; 454a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn if (getRowHeight() != getExpandedRowHeight()) { 455a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn int newHeight = expanded ? getExpandedRowHeight() : getRowHeight(); 456a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn vh.getGridView().setRowHeight(newHeight); 457a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn } 4584cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout setVerticalPadding(vh); 45947520b68e50572a9775a662410c5aff8300c8784Craig Stout updateFooterViewSwitcher(vh); 46047520b68e50572a9775a662410c5aff8300c8784Craig Stout } 46147520b68e50572a9775a662410c5aff8300c8784Craig Stout 46247520b68e50572a9775a662410c5aff8300c8784Craig Stout @Override 463cb13a318e577e14461eb008071dddf762847de42Dake Gu protected void onBindRowViewHolder(RowPresenter.ViewHolder holder, Object item) { 464cb13a318e577e14461eb008071dddf762847de42Dake Gu super.onBindRowViewHolder(holder, item); 465cb13a318e577e14461eb008071dddf762847de42Dake Gu ViewHolder vh = (ViewHolder) holder; 46647520b68e50572a9775a662410c5aff8300c8784Craig Stout ListRow rowItem = (ListRow) item; 46747520b68e50572a9775a662410c5aff8300c8784Craig Stout vh.mItemBridgeAdapter.setAdapter(rowItem.getAdapter()); 46847520b68e50572a9775a662410c5aff8300c8784Craig Stout vh.mGridView.setAdapter(vh.mItemBridgeAdapter); 46947520b68e50572a9775a662410c5aff8300c8784Craig Stout } 47047520b68e50572a9775a662410c5aff8300c8784Craig Stout 47147520b68e50572a9775a662410c5aff8300c8784Craig Stout @Override 472cb13a318e577e14461eb008071dddf762847de42Dake Gu protected void onUnbindRowViewHolder(RowPresenter.ViewHolder holder) { 4735358b0ca6ed795892bd097fdf15d41fb6b1a03d2Craig Stout ViewHolder vh = (ViewHolder) holder; 4745358b0ca6ed795892bd097fdf15d41fb6b1a03d2Craig Stout vh.mGridView.setAdapter(null); 4755358b0ca6ed795892bd097fdf15d41fb6b1a03d2Craig Stout vh.mItemBridgeAdapter.clear(); 476cb13a318e577e14461eb008071dddf762847de42Dake Gu super.onUnbindRowViewHolder(holder); 47747520b68e50572a9775a662410c5aff8300c8784Craig Stout } 47847520b68e50572a9775a662410c5aff8300c8784Craig Stout 479cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu /** 480cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu * ListRowPresenter overrides the default select effect of {@link RowPresenter} 481cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu * and return false. 482cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu */ 483cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu @Override 484cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu public final boolean isUsingDefaultSelectEffect() { 485cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu return false; 486cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu } 487cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu 488cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu /** 489cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu * Returns true so that default select effect is applied to each individual 490cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu * child of {@link HorizontalGridView}. Subclass may return false to disable 491cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu * the default implementation. 492cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu * @see #onSelectLevelChanged(RowPresenter.ViewHolder) 493cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu */ 494cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu public boolean isUsingDefaultListSelectEffect() { 495cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu return true; 496cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu } 497cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu 498cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu /** 499dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu * Returns true if SDK >= 18, where default shadow 500892181367d658f347d00ea5e091aa31f086b2a20Dake Gu * is applied to each individual child of {@link HorizontalGridView}. 501892181367d658f347d00ea5e091aa31f086b2a20Dake Gu * Subclass may return false to disable. 502892181367d658f347d00ea5e091aa31f086b2a20Dake Gu */ 503892181367d658f347d00ea5e091aa31f086b2a20Dake Gu public boolean isUsingDefaultShadow() { 504dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu return ShadowOverlayContainer.supportsShadow(); 505892181367d658f347d00ea5e091aa31f086b2a20Dake Gu } 506892181367d658f347d00ea5e091aa31f086b2a20Dake Gu 507892181367d658f347d00ea5e091aa31f086b2a20Dake Gu /** 5080fcad32410ad29031630bb9cc2da35d33a4aa906Dake Gu * Returns true if SDK >= L, where Z shadow is enabled so that Z order is enabled 5090fcad32410ad29031630bb9cc2da35d33a4aa906Dake Gu * on each child of horizontal list. If subclass returns false in isUsingDefaultShadow() 5100fcad32410ad29031630bb9cc2da35d33a4aa906Dake Gu * and does not use Z-shadow on SDK >= L, it should override isUsingZOrder() return false. 5110fcad32410ad29031630bb9cc2da35d33a4aa906Dake Gu */ 5120fcad32410ad29031630bb9cc2da35d33a4aa906Dake Gu public boolean isUsingZOrder() { 5130fcad32410ad29031630bb9cc2da35d33a4aa906Dake Gu return ShadowHelper.getInstance().usesZShadow(); 5140fcad32410ad29031630bb9cc2da35d33a4aa906Dake Gu } 5150fcad32410ad29031630bb9cc2da35d33a4aa906Dake Gu 5160fcad32410ad29031630bb9cc2da35d33a4aa906Dake Gu /** 517892181367d658f347d00ea5e091aa31f086b2a20Dake Gu * Enable or disable child shadow. 518892181367d658f347d00ea5e091aa31f086b2a20Dake Gu * This is not only for enable/disable default shadow implementation but also subclass must 519892181367d658f347d00ea5e091aa31f086b2a20Dake Gu * respect this flag. 520892181367d658f347d00ea5e091aa31f086b2a20Dake Gu */ 521892181367d658f347d00ea5e091aa31f086b2a20Dake Gu public final void setShadowEnabled(boolean enabled) { 522892181367d658f347d00ea5e091aa31f086b2a20Dake Gu mShadowEnabled = enabled; 523892181367d658f347d00ea5e091aa31f086b2a20Dake Gu } 524892181367d658f347d00ea5e091aa31f086b2a20Dake Gu 525892181367d658f347d00ea5e091aa31f086b2a20Dake Gu /** 526892181367d658f347d00ea5e091aa31f086b2a20Dake Gu * Returns true if child shadow is enabled. 527892181367d658f347d00ea5e091aa31f086b2a20Dake Gu * This is not only for enable/disable default shadow implementation but also subclass must 528892181367d658f347d00ea5e091aa31f086b2a20Dake Gu * respect this flag. 529892181367d658f347d00ea5e091aa31f086b2a20Dake Gu */ 530892181367d658f347d00ea5e091aa31f086b2a20Dake Gu public final boolean getShadowEnabled() { 531892181367d658f347d00ea5e091aa31f086b2a20Dake Gu return mShadowEnabled; 532892181367d658f347d00ea5e091aa31f086b2a20Dake Gu } 533892181367d658f347d00ea5e091aa31f086b2a20Dake Gu 5344f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout /** 5354f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout * Enables or disabled rounded corners on children of this row. 5364f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout * Supported on Android SDK >= L. 5374f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout */ 5384f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout public final void enableChildRoundedCorners(boolean enable) { 5394f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout mRoundedCornersEnabled = enable; 5404f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout } 5414f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout 5424f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout /** 5434f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout * Returns true if rounded corners are enabled for children of this row. 5444f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout */ 5454f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout public final boolean areChildRoundedCornersEnabled() { 5464f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout return mRoundedCornersEnabled; 5474f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout } 5484f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout 549892181367d658f347d00ea5e091aa31f086b2a20Dake Gu final boolean needsDefaultShadow() { 550892181367d658f347d00ea5e091aa31f086b2a20Dake Gu return isUsingDefaultShadow() && getShadowEnabled(); 551892181367d658f347d00ea5e091aa31f086b2a20Dake Gu } 552892181367d658f347d00ea5e091aa31f086b2a20Dake Gu 553892181367d658f347d00ea5e091aa31f086b2a20Dake Gu @Override 554892181367d658f347d00ea5e091aa31f086b2a20Dake Gu public boolean canDrawOutOfBounds() { 555892181367d658f347d00ea5e091aa31f086b2a20Dake Gu return needsDefaultShadow(); 556892181367d658f347d00ea5e091aa31f086b2a20Dake Gu } 557892181367d658f347d00ea5e091aa31f086b2a20Dake Gu 558892181367d658f347d00ea5e091aa31f086b2a20Dake Gu /** 559cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu * Applies select level to header and draw a default color dim over each child 560cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu * of {@link HorizontalGridView}. 561cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu * <p> 562cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu * Subclass may override this method. A subclass 563cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu * needs to call super.onSelectLevelChanged() for applying header select level 564cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu * and optionally applying a default select level to each child view of 565cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu * {@link HorizontalGridView} if {@link #isUsingDefaultListSelectEffect()} 566cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu * is true. Subclass may override {@link #isUsingDefaultListSelectEffect()} to return 567cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu * false and deal with the individual item select level by itself. 568cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu * </p> 569cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu */ 570cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu @Override 571cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu protected void onSelectLevelChanged(RowPresenter.ViewHolder holder) { 572cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu super.onSelectLevelChanged(holder); 573cb13a318e577e14461eb008071dddf762847de42Dake Gu if (needsDefaultListSelectEffect()) { 574cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu ViewHolder vh = (ViewHolder) holder; 575892181367d658f347d00ea5e091aa31f086b2a20Dake Gu int dimmedColor = vh.mColorDimmer.getPaint().getColor(); 576892181367d658f347d00ea5e091aa31f086b2a20Dake Gu for (int i = 0, count = vh.mGridView.getChildCount(); i < count; i++) { 577dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu ShadowOverlayContainer wrapper = (ShadowOverlayContainer) vh.mGridView.getChildAt(i); 578dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu wrapper.setOverlayColor(dimmedColor); 579cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu } 5809240e796bc63422c28f2707840bd99c48573279bDake Gu if (vh.mGridView.getFadingLeftEdge()) { 5819240e796bc63422c28f2707840bd99c48573279bDake Gu vh.mGridView.invalidate(); 5829240e796bc63422c28f2707840bd99c48573279bDake Gu } 583cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu } 584cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu } 585cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu 586709bb7083a089e788d84ffa81f2c4f60a1bc8cf2Dake Gu @Override 587709bb7083a089e788d84ffa81f2c4f60a1bc8cf2Dake Gu public void freeze(RowPresenter.ViewHolder holder, boolean freeze) { 588709bb7083a089e788d84ffa81f2c4f60a1bc8cf2Dake Gu ViewHolder vh = (ViewHolder) holder; 589709bb7083a089e788d84ffa81f2c4f60a1bc8cf2Dake Gu vh.mGridView.setScrollEnabled(!freeze); 590709bb7083a089e788d84ffa81f2c4f60a1bc8cf2Dake Gu } 591709bb7083a089e788d84ffa81f2c4f60a1bc8cf2Dake Gu 592c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu @Override 5933f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu public void setEntranceTransitionState(RowPresenter.ViewHolder holder, 5943f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu boolean afterEntrance) { 5953f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu super.setEntranceTransitionState(holder, afterEntrance); 596c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu ((ViewHolder) holder).mGridView.setChildrenVisibility( 5973f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu afterEntrance? View.VISIBLE : View.INVISIBLE); 598c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu } 59947520b68e50572a9775a662410c5aff8300c8784Craig Stout} 600