ListRowPresenter.java revision dfd01bbadc107b6b3b2081ddb0236128c425f380
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 1647520b68e50572a9775a662410c5aff8300c8784Craig Stoutimport java.util.ArrayList; 1747520b68e50572a9775a662410c5aff8300c8784Craig Stout 18892181367d658f347d00ea5e091aa31f086b2a20Dake Guimport android.content.Context; 19cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Guimport android.graphics.Canvas; 20892181367d658f347d00ea5e091aa31f086b2a20Dake Guimport android.support.v17.leanback.R; 21cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Guimport android.support.v17.leanback.graphics.ColorOverlayDimmer; 2247520b68e50572a9775a662410c5aff8300c8784Craig Stoutimport android.support.v17.leanback.widget.Presenter.ViewHolder; 23cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Guimport android.support.v7.widget.RecyclerView; 24892181367d658f347d00ea5e091aa31f086b2a20Dake Guimport android.util.AttributeSet; 2547520b68e50572a9775a662410c5aff8300c8784Craig Stoutimport android.view.View; 2647520b68e50572a9775a662410c5aff8300c8784Craig Stoutimport android.view.ViewGroup; 27892181367d658f347d00ea5e091aa31f086b2a20Dake Guimport android.view.ViewGroup.LayoutParams; 28892181367d658f347d00ea5e091aa31f086b2a20Dake Guimport android.widget.FrameLayout; 2947520b68e50572a9775a662410c5aff8300c8784Craig Stout 3047520b68e50572a9775a662410c5aff8300c8784Craig Stout/** 317aaa6c6ef8807cc4ea4c4642716d6e30056bc4ebDake Gu * ListRowPresenter renders {@link ListRow} using a 327aaa6c6ef8807cc4ea4c4642716d6e30056bc4ebDake Gu * {@link HorizontalGridView} hosted in a {@link BrowseRowView}. 337aaa6c6ef8807cc4ea4c4642716d6e30056bc4ebDake Gu * 347aaa6c6ef8807cc4ea4c4642716d6e30056bc4ebDake Gu * <h3>Hover card</h3> 3547520b68e50572a9775a662410c5aff8300c8784Craig Stout * Optionally, {@link #setHoverCardPresenterSelector(PresenterSelector)} can be used to 3647520b68e50572a9775a662410c5aff8300c8784Craig Stout * display a view for the currently focused list item below the rendered 3747520b68e50572a9775a662410c5aff8300c8784Craig Stout * list. This view is known as a hover card. 387aaa6c6ef8807cc4ea4c4642716d6e30056bc4ebDake Gu * 397aaa6c6ef8807cc4ea4c4642716d6e30056bc4ebDake Gu * <h3>Selection animation</h3> 407aaa6c6ef8807cc4ea4c4642716d6e30056bc4ebDake Gu * ListRowPresenter disables {@link RowPresenter}'s default dimming effect and draw 417aaa6c6ef8807cc4ea4c4642716d6e30056bc4ebDake Gu * a dim overlay on top of each individual child items. Subclass may override and disable 427aaa6c6ef8807cc4ea4c4642716d6e30056bc4ebDake Gu * {@link #isUsingDefaultListSelectEffect()} and write its own dim effect in 437aaa6c6ef8807cc4ea4c4642716d6e30056bc4ebDake Gu * {@link #onSelectLevelChanged(RowPresenter.ViewHolder)}. 44dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu * 45dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu * <h3>Shadow</h3> 46dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu * ListRowPresenter applies a default shadow to child of each view. Call 47dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu * {@link #setShadowEnabled(boolean)} to disable shadow. Subclass may override and return 48dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu * false in {@link #isUsingDefaultShadow()} and replace with its own shadow implementation. 4947520b68e50572a9775a662410c5aff8300c8784Craig Stout */ 5047520b68e50572a9775a662410c5aff8300c8784Craig Stoutpublic class ListRowPresenter extends RowPresenter { 5147520b68e50572a9775a662410c5aff8300c8784Craig Stout 5247520b68e50572a9775a662410c5aff8300c8784Craig Stout private static final String TAG = "ListRowPresenter"; 5347520b68e50572a9775a662410c5aff8300c8784Craig Stout private static final boolean DEBUG = false; 5447520b68e50572a9775a662410c5aff8300c8784Craig Stout 5562d5de70439cb859525e45310b5ac4dbbfe420f2Tim Kilbourn /** 5662d5de70439cb859525e45310b5ac4dbbfe420f2Tim Kilbourn * No zoom factor. 5762d5de70439cb859525e45310b5ac4dbbfe420f2Tim Kilbourn * @deprecated Use {@link FocusHighlight#ZOOM_FACTOR_NONE} instead. 5862d5de70439cb859525e45310b5ac4dbbfe420f2Tim Kilbourn */ 5962d5de70439cb859525e45310b5ac4dbbfe420f2Tim Kilbourn @Deprecated 6062d5de70439cb859525e45310b5ac4dbbfe420f2Tim Kilbourn public static final int ZOOM_FACTOR_NONE = FocusHighlight.ZOOM_FACTOR_NONE; 6162d5de70439cb859525e45310b5ac4dbbfe420f2Tim Kilbourn 6262d5de70439cb859525e45310b5ac4dbbfe420f2Tim Kilbourn /** 6362d5de70439cb859525e45310b5ac4dbbfe420f2Tim Kilbourn * A small zoom factor, recommended for large item views. 6462d5de70439cb859525e45310b5ac4dbbfe420f2Tim Kilbourn * @deprecated Use {@link FocusHighlight#ZOOM_FACTOR_SMALL} instead. 6562d5de70439cb859525e45310b5ac4dbbfe420f2Tim Kilbourn */ 6662d5de70439cb859525e45310b5ac4dbbfe420f2Tim Kilbourn @Deprecated 6762d5de70439cb859525e45310b5ac4dbbfe420f2Tim Kilbourn public static final int ZOOM_FACTOR_SMALL = FocusHighlight.ZOOM_FACTOR_SMALL; 6862d5de70439cb859525e45310b5ac4dbbfe420f2Tim Kilbourn 6962d5de70439cb859525e45310b5ac4dbbfe420f2Tim Kilbourn /** 7062d5de70439cb859525e45310b5ac4dbbfe420f2Tim Kilbourn * A medium zoom factor, recommended for medium sized item views. 7162d5de70439cb859525e45310b5ac4dbbfe420f2Tim Kilbourn * @deprecated Use {@link FocusHighlight#ZOOM_FACTOR_MEDIUM} instead. 7262d5de70439cb859525e45310b5ac4dbbfe420f2Tim Kilbourn */ 7362d5de70439cb859525e45310b5ac4dbbfe420f2Tim Kilbourn @Deprecated 7462d5de70439cb859525e45310b5ac4dbbfe420f2Tim Kilbourn public static final int ZOOM_FACTOR_MEDIUM = FocusHighlight.ZOOM_FACTOR_MEDIUM; 7562d5de70439cb859525e45310b5ac4dbbfe420f2Tim Kilbourn 7662d5de70439cb859525e45310b5ac4dbbfe420f2Tim Kilbourn /** 7762d5de70439cb859525e45310b5ac4dbbfe420f2Tim Kilbourn * A large zoom factor, recommended for small item views. 7862d5de70439cb859525e45310b5ac4dbbfe420f2Tim Kilbourn * @deprecated Use {@link FocusHighlight#ZOOM_FACTOR_LARGE} instead. 7962d5de70439cb859525e45310b5ac4dbbfe420f2Tim Kilbourn */ 8062d5de70439cb859525e45310b5ac4dbbfe420f2Tim Kilbourn @Deprecated 8162d5de70439cb859525e45310b5ac4dbbfe420f2Tim Kilbourn public static final int ZOOM_FACTOR_LARGE = FocusHighlight.ZOOM_FACTOR_LARGE; 8262d5de70439cb859525e45310b5ac4dbbfe420f2Tim Kilbourn 8347520b68e50572a9775a662410c5aff8300c8784Craig Stout public static class ViewHolder extends RowPresenter.ViewHolder { 8447520b68e50572a9775a662410c5aff8300c8784Craig Stout final ListRowPresenter mListRowPresenter; 8547520b68e50572a9775a662410c5aff8300c8784Craig Stout final HorizontalGridView mGridView; 8647520b68e50572a9775a662410c5aff8300c8784Craig Stout final ItemBridgeAdapter mItemBridgeAdapter = new ItemBridgeAdapter(); 8747520b68e50572a9775a662410c5aff8300c8784Craig Stout final HorizontalHoverCardSwitcher mHoverCardViewSwitcher = new HorizontalHoverCardSwitcher(); 88cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu final ColorOverlayDimmer mColorDimmer; 8947520b68e50572a9775a662410c5aff8300c8784Craig Stout 9047520b68e50572a9775a662410c5aff8300c8784Craig Stout public ViewHolder(View rootView, HorizontalGridView gridView, ListRowPresenter p) { 9147520b68e50572a9775a662410c5aff8300c8784Craig Stout super(rootView); 9247520b68e50572a9775a662410c5aff8300c8784Craig Stout mGridView = gridView; 9347520b68e50572a9775a662410c5aff8300c8784Craig Stout mListRowPresenter = p; 94cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu mColorDimmer = ColorOverlayDimmer.createDefault(rootView.getContext()); 9547520b68e50572a9775a662410c5aff8300c8784Craig Stout } 9647520b68e50572a9775a662410c5aff8300c8784Craig Stout 9747520b68e50572a9775a662410c5aff8300c8784Craig Stout public final ListRowPresenter getListRowPresenter() { 9847520b68e50572a9775a662410c5aff8300c8784Craig Stout return mListRowPresenter; 9947520b68e50572a9775a662410c5aff8300c8784Craig Stout } 10047520b68e50572a9775a662410c5aff8300c8784Craig Stout 10147520b68e50572a9775a662410c5aff8300c8784Craig Stout public final HorizontalGridView getGridView() { 10247520b68e50572a9775a662410c5aff8300c8784Craig Stout return mGridView; 10347520b68e50572a9775a662410c5aff8300c8784Craig Stout } 10447520b68e50572a9775a662410c5aff8300c8784Craig Stout } 10547520b68e50572a9775a662410c5aff8300c8784Craig Stout 10647520b68e50572a9775a662410c5aff8300c8784Craig Stout private PresenterSelector mHoverCardPresenterSelector; 107b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout private int mZoomFactor; 108892181367d658f347d00ea5e091aa31f086b2a20Dake Gu private boolean mShadowEnabled = true; 109b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout 110b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout /** 111b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout * Constructs a ListRowPresenter with defaults. 112739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout * Uses {@link FocusHighlight#ZOOM_FACTOR_MEDIUM} for focus zooming. 113b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout */ 114b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout public ListRowPresenter() { 115739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout this(FocusHighlight.ZOOM_FACTOR_MEDIUM); 116b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout } 117b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout 118b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout /** 119b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout * Constructs a ListRowPresenter with the given parameters. 120b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout * 121b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout * @param zoomFactor Controls the zoom factor used when an item view is focused. One of 122739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout * {@link FocusHighlight#ZOOM_FACTOR_NONE}, 123739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout * {@link FocusHighlight#ZOOM_FACTOR_SMALL}, 124739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout * {@link FocusHighlight#ZOOM_FACTOR_MEDIUM}, 125739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout * {@link FocusHighlight#ZOOM_FACTOR_LARGE} 126b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout */ 127b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout public ListRowPresenter(int zoomFactor) { 128b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout mZoomFactor = zoomFactor; 129b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout } 130b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout 131b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout /** 132b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout * Returns the zoom factor used for focus highlighting. 133b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout */ 134b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout public final int getZoomFactor() { 135b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout return mZoomFactor; 136b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout } 13747520b68e50572a9775a662410c5aff8300c8784Craig Stout 138892181367d658f347d00ea5e091aa31f086b2a20Dake Gu private ItemBridgeAdapter.Wrapper mCardWrapper = new ItemBridgeAdapter.Wrapper() { 139892181367d658f347d00ea5e091aa31f086b2a20Dake Gu @Override 140892181367d658f347d00ea5e091aa31f086b2a20Dake Gu public View createWrapper(View root) { 141dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu ShadowOverlayContainer wrapper = new ShadowOverlayContainer(root.getContext()); 142892181367d658f347d00ea5e091aa31f086b2a20Dake Gu wrapper.setLayoutParams( 143892181367d658f347d00ea5e091aa31f086b2a20Dake Gu new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); 144892181367d658f347d00ea5e091aa31f086b2a20Dake Gu wrapper.initialize(needsDefaultShadow(), needsDefaultSelectEffect()); 145892181367d658f347d00ea5e091aa31f086b2a20Dake Gu return wrapper; 146892181367d658f347d00ea5e091aa31f086b2a20Dake Gu } 147892181367d658f347d00ea5e091aa31f086b2a20Dake Gu @Override 148892181367d658f347d00ea5e091aa31f086b2a20Dake Gu public void wrap(View wrapper, View wrapped) { 149dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu ((ShadowOverlayContainer) wrapper).wrap(wrapped); 150892181367d658f347d00ea5e091aa31f086b2a20Dake Gu } 151892181367d658f347d00ea5e091aa31f086b2a20Dake Gu }; 152892181367d658f347d00ea5e091aa31f086b2a20Dake Gu 15347520b68e50572a9775a662410c5aff8300c8784Craig Stout @Override 15447520b68e50572a9775a662410c5aff8300c8784Craig Stout protected void initializeRowViewHolder(RowPresenter.ViewHolder holder) { 15547520b68e50572a9775a662410c5aff8300c8784Craig Stout super.initializeRowViewHolder(holder); 15647520b68e50572a9775a662410c5aff8300c8784Craig Stout final ViewHolder rowViewHolder = (ViewHolder) holder; 157892181367d658f347d00ea5e091aa31f086b2a20Dake Gu if (needsDefaultSelectEffect() || needsDefaultShadow()) { 158892181367d658f347d00ea5e091aa31f086b2a20Dake Gu rowViewHolder.mItemBridgeAdapter.setWrapper(mCardWrapper); 159892181367d658f347d00ea5e091aa31f086b2a20Dake Gu } 160892181367d658f347d00ea5e091aa31f086b2a20Dake Gu if (needsDefaultShadow()) { 161dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu ShadowOverlayContainer.prepareParentForShadow(rowViewHolder.mGridView); 162892181367d658f347d00ea5e091aa31f086b2a20Dake Gu ((ViewGroup) rowViewHolder.view).setClipChildren(false); 163cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu } 164b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout FocusHighlightHelper.setupBrowseItemFocusHighlight(rowViewHolder.mItemBridgeAdapter, mZoomFactor); 16547520b68e50572a9775a662410c5aff8300c8784Craig Stout rowViewHolder.mGridView.setOnChildSelectedListener( 16647520b68e50572a9775a662410c5aff8300c8784Craig Stout new OnChildSelectedListener() { 16747520b68e50572a9775a662410c5aff8300c8784Craig Stout @Override 16847520b68e50572a9775a662410c5aff8300c8784Craig Stout public void onChildSelected(ViewGroup parent, View view, int position, long id) { 16947520b68e50572a9775a662410c5aff8300c8784Craig Stout selectChildView(rowViewHolder, view); 17047520b68e50572a9775a662410c5aff8300c8784Craig Stout } 17147520b68e50572a9775a662410c5aff8300c8784Craig Stout }); 172892181367d658f347d00ea5e091aa31f086b2a20Dake Gu rowViewHolder.mItemBridgeAdapter.setAdapterListener( 173892181367d658f347d00ea5e091aa31f086b2a20Dake Gu new ItemBridgeAdapter.AdapterListener() { 174892181367d658f347d00ea5e091aa31f086b2a20Dake Gu @Override 175892181367d658f347d00ea5e091aa31f086b2a20Dake Gu public void onCreate(final ItemBridgeAdapter.ViewHolder viewHolder) { 176892181367d658f347d00ea5e091aa31f086b2a20Dake Gu // Only when having an OnItemClickListner, we will attach the OnClickListener. 177892181367d658f347d00ea5e091aa31f086b2a20Dake Gu if (getOnItemClickedListener() != null) { 17847520b68e50572a9775a662410c5aff8300c8784Craig Stout viewHolder.mHolder.view.setOnClickListener(new View.OnClickListener() { 17947520b68e50572a9775a662410c5aff8300c8784Craig Stout @Override 18047520b68e50572a9775a662410c5aff8300c8784Craig Stout public void onClick(View v) { 18147520b68e50572a9775a662410c5aff8300c8784Craig Stout ItemBridgeAdapter.ViewHolder ibh = (ItemBridgeAdapter.ViewHolder) 182892181367d658f347d00ea5e091aa31f086b2a20Dake Gu rowViewHolder.mGridView.getChildViewHolder(viewHolder.itemView); 18347520b68e50572a9775a662410c5aff8300c8784Craig Stout if (getOnItemClickedListener() != null) { 18447520b68e50572a9775a662410c5aff8300c8784Craig Stout getOnItemClickedListener().onItemClicked(ibh.mItem, 18547520b68e50572a9775a662410c5aff8300c8784Craig Stout (ListRow) rowViewHolder.mRow); 18647520b68e50572a9775a662410c5aff8300c8784Craig Stout } 18747520b68e50572a9775a662410c5aff8300c8784Craig Stout } 18847520b68e50572a9775a662410c5aff8300c8784Craig Stout }); 18947520b68e50572a9775a662410c5aff8300c8784Craig Stout } 190892181367d658f347d00ea5e091aa31f086b2a20Dake Gu } 191892181367d658f347d00ea5e091aa31f086b2a20Dake Gu 192892181367d658f347d00ea5e091aa31f086b2a20Dake Gu @Override 19329246e5ca814f17dcf368eeacd1b44a329592ae0Dake Gu public void onAttachedToWindow(ItemBridgeAdapter.ViewHolder viewHolder) { 194dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu if (viewHolder.itemView instanceof ShadowOverlayContainer) { 195892181367d658f347d00ea5e091aa31f086b2a20Dake Gu int dimmedColor = rowViewHolder.mColorDimmer.getPaint().getColor(); 196dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu ((ShadowOverlayContainer) viewHolder.itemView).setOverlayColor(dimmedColor); 197892181367d658f347d00ea5e091aa31f086b2a20Dake Gu } 198892181367d658f347d00ea5e091aa31f086b2a20Dake Gu } 199892181367d658f347d00ea5e091aa31f086b2a20Dake Gu }); 20047520b68e50572a9775a662410c5aff8300c8784Craig Stout } 20147520b68e50572a9775a662410c5aff8300c8784Craig Stout 202892181367d658f347d00ea5e091aa31f086b2a20Dake Gu final boolean needsDefaultSelectEffect() { 203cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu return isUsingDefaultListSelectEffect() && getSelectEffectEnabled(); 204cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu } 205cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu 20647520b68e50572a9775a662410c5aff8300c8784Craig Stout /** 20747520b68e50572a9775a662410c5aff8300c8784Craig Stout * Set {@link PresenterSelector} used for showing a select object in a hover card. 20847520b68e50572a9775a662410c5aff8300c8784Craig Stout */ 20947520b68e50572a9775a662410c5aff8300c8784Craig Stout public final void setHoverCardPresenterSelector(PresenterSelector selector) { 21047520b68e50572a9775a662410c5aff8300c8784Craig Stout mHoverCardPresenterSelector = selector; 21147520b68e50572a9775a662410c5aff8300c8784Craig Stout } 21247520b68e50572a9775a662410c5aff8300c8784Craig Stout 21347520b68e50572a9775a662410c5aff8300c8784Craig Stout /** 21447520b68e50572a9775a662410c5aff8300c8784Craig Stout * Get {@link PresenterSelector} used for showing a select object in a hover card. 21547520b68e50572a9775a662410c5aff8300c8784Craig Stout */ 21647520b68e50572a9775a662410c5aff8300c8784Craig Stout public final PresenterSelector getHoverCardPresenterSelector() { 21747520b68e50572a9775a662410c5aff8300c8784Craig Stout return mHoverCardPresenterSelector; 21847520b68e50572a9775a662410c5aff8300c8784Craig Stout } 21947520b68e50572a9775a662410c5aff8300c8784Craig Stout 22047520b68e50572a9775a662410c5aff8300c8784Craig Stout /* 22147520b68e50572a9775a662410c5aff8300c8784Craig Stout * Perform operations when a child of horizontal grid view is selected. 22247520b68e50572a9775a662410c5aff8300c8784Craig Stout */ 22347520b68e50572a9775a662410c5aff8300c8784Craig Stout private void selectChildView(ViewHolder rowViewHolder, View view) { 22447520b68e50572a9775a662410c5aff8300c8784Craig Stout ItemBridgeAdapter.ViewHolder ibh = null; 22547520b68e50572a9775a662410c5aff8300c8784Craig Stout if (view != null) { 22647520b68e50572a9775a662410c5aff8300c8784Craig Stout ibh = (ItemBridgeAdapter.ViewHolder) 22747520b68e50572a9775a662410c5aff8300c8784Craig Stout rowViewHolder.mGridView.getChildViewHolder(view); 22847520b68e50572a9775a662410c5aff8300c8784Craig Stout } 22947520b68e50572a9775a662410c5aff8300c8784Craig Stout if (view == null) { 23047520b68e50572a9775a662410c5aff8300c8784Craig Stout if (mHoverCardPresenterSelector != null) { 23147520b68e50572a9775a662410c5aff8300c8784Craig Stout rowViewHolder.mHoverCardViewSwitcher.unselect(); 23247520b68e50572a9775a662410c5aff8300c8784Craig Stout } 23347520b68e50572a9775a662410c5aff8300c8784Craig Stout if (getOnItemSelectedListener() != null) { 23447520b68e50572a9775a662410c5aff8300c8784Craig Stout getOnItemSelectedListener().onItemSelected(null, rowViewHolder.mRow); 23547520b68e50572a9775a662410c5aff8300c8784Craig Stout } 23647520b68e50572a9775a662410c5aff8300c8784Craig Stout } else if (rowViewHolder.mExpanded && rowViewHolder.mSelected) { 23747520b68e50572a9775a662410c5aff8300c8784Craig Stout if (mHoverCardPresenterSelector != null) { 23847520b68e50572a9775a662410c5aff8300c8784Craig Stout rowViewHolder.mHoverCardViewSwitcher.select(rowViewHolder.mGridView, view, 23947520b68e50572a9775a662410c5aff8300c8784Craig Stout ibh.mItem); 24047520b68e50572a9775a662410c5aff8300c8784Craig Stout } 24147520b68e50572a9775a662410c5aff8300c8784Craig Stout if (getOnItemSelectedListener() != null) { 24247520b68e50572a9775a662410c5aff8300c8784Craig Stout getOnItemSelectedListener().onItemSelected(ibh.mItem, rowViewHolder.mRow); 24347520b68e50572a9775a662410c5aff8300c8784Craig Stout } 24447520b68e50572a9775a662410c5aff8300c8784Craig Stout } 24547520b68e50572a9775a662410c5aff8300c8784Craig Stout } 24647520b68e50572a9775a662410c5aff8300c8784Craig Stout 24747520b68e50572a9775a662410c5aff8300c8784Craig Stout @Override 24847520b68e50572a9775a662410c5aff8300c8784Craig Stout protected RowPresenter.ViewHolder createRowViewHolder(ViewGroup parent) { 24947520b68e50572a9775a662410c5aff8300c8784Craig Stout BrowseRowView rowView = new BrowseRowView(parent.getContext()); 25047520b68e50572a9775a662410c5aff8300c8784Craig Stout return new ViewHolder(rowView, rowView.getGridView(), this); 25147520b68e50572a9775a662410c5aff8300c8784Craig Stout } 25247520b68e50572a9775a662410c5aff8300c8784Craig Stout 25347520b68e50572a9775a662410c5aff8300c8784Craig Stout @Override 25447520b68e50572a9775a662410c5aff8300c8784Craig Stout protected void onRowViewSelected(RowPresenter.ViewHolder holder, boolean selected) { 25547520b68e50572a9775a662410c5aff8300c8784Craig Stout updateFooterViewSwitcher((ViewHolder) holder); 25647520b68e50572a9775a662410c5aff8300c8784Craig Stout updateInitialChildSelection((ViewHolder) holder); 25747520b68e50572a9775a662410c5aff8300c8784Craig Stout } 25847520b68e50572a9775a662410c5aff8300c8784Craig Stout 25947520b68e50572a9775a662410c5aff8300c8784Craig Stout /* 26047520b68e50572a9775a662410c5aff8300c8784Craig Stout * Show or hide hover card when row selection or expanded state is changed. 26147520b68e50572a9775a662410c5aff8300c8784Craig Stout */ 26247520b68e50572a9775a662410c5aff8300c8784Craig Stout private void updateFooterViewSwitcher(ViewHolder vh) { 26347520b68e50572a9775a662410c5aff8300c8784Craig Stout if (vh.mExpanded && vh.mSelected) { 26447520b68e50572a9775a662410c5aff8300c8784Craig Stout if (mHoverCardPresenterSelector != null) { 26547520b68e50572a9775a662410c5aff8300c8784Craig Stout vh.mHoverCardViewSwitcher.init((ViewGroup) vh.view, 26647520b68e50572a9775a662410c5aff8300c8784Craig Stout mHoverCardPresenterSelector); 26747520b68e50572a9775a662410c5aff8300c8784Craig Stout } 26847520b68e50572a9775a662410c5aff8300c8784Craig Stout } else { 26947520b68e50572a9775a662410c5aff8300c8784Craig Stout if (mHoverCardPresenterSelector != null) { 27047520b68e50572a9775a662410c5aff8300c8784Craig Stout vh.mHoverCardViewSwitcher.clear(); 27147520b68e50572a9775a662410c5aff8300c8784Craig Stout } 27247520b68e50572a9775a662410c5aff8300c8784Craig Stout } 27347520b68e50572a9775a662410c5aff8300c8784Craig Stout } 27447520b68e50572a9775a662410c5aff8300c8784Craig Stout 27547520b68e50572a9775a662410c5aff8300c8784Craig Stout /* 27647520b68e50572a9775a662410c5aff8300c8784Craig Stout * Make initial child selection when row selection state is changed. 27747520b68e50572a9775a662410c5aff8300c8784Craig Stout */ 27847520b68e50572a9775a662410c5aff8300c8784Craig Stout private void updateInitialChildSelection(ViewHolder vh) { 27947520b68e50572a9775a662410c5aff8300c8784Craig Stout if (vh.mExpanded && vh.mSelected) { 28047520b68e50572a9775a662410c5aff8300c8784Craig Stout ItemBridgeAdapter.ViewHolder ibh = (ItemBridgeAdapter.ViewHolder) 28147520b68e50572a9775a662410c5aff8300c8784Craig Stout vh.mGridView.findViewHolderForPosition( 282025aa57d4fdd4e79289303c7dc54169311728f7bCraig Stout vh.mGridView.getSelectedPosition()); 283892181367d658f347d00ea5e091aa31f086b2a20Dake Gu selectChildView(vh, ibh == null ? null : ibh.itemView); 28447520b68e50572a9775a662410c5aff8300c8784Craig Stout } else { 28547520b68e50572a9775a662410c5aff8300c8784Craig Stout selectChildView(vh, null); 28647520b68e50572a9775a662410c5aff8300c8784Craig Stout } 28747520b68e50572a9775a662410c5aff8300c8784Craig Stout } 28847520b68e50572a9775a662410c5aff8300c8784Craig Stout 28947520b68e50572a9775a662410c5aff8300c8784Craig Stout @Override 29047520b68e50572a9775a662410c5aff8300c8784Craig Stout protected void onRowViewExpanded(RowPresenter.ViewHolder holder, boolean expanded) { 29147520b68e50572a9775a662410c5aff8300c8784Craig Stout super.onRowViewExpanded(holder, expanded); 29247520b68e50572a9775a662410c5aff8300c8784Craig Stout ViewHolder vh = (ViewHolder) holder; 29347520b68e50572a9775a662410c5aff8300c8784Craig Stout vh.mGridView.setClipToPadding(!expanded); 294db1e9bb04638eb6b0b16e849e433d1c3b6f4296cDake Gu vh.mGridView.invalidate(); 29547520b68e50572a9775a662410c5aff8300c8784Craig Stout updateFooterViewSwitcher(vh); 29647520b68e50572a9775a662410c5aff8300c8784Craig Stout } 29747520b68e50572a9775a662410c5aff8300c8784Craig Stout 29847520b68e50572a9775a662410c5aff8300c8784Craig Stout @Override 29947520b68e50572a9775a662410c5aff8300c8784Craig Stout public void onBindViewHolder(Presenter.ViewHolder holder, Object item) { 30047520b68e50572a9775a662410c5aff8300c8784Craig Stout super.onBindViewHolder(holder, item); 30147520b68e50572a9775a662410c5aff8300c8784Craig Stout ViewHolder vh = (ViewHolder)holder; 30247520b68e50572a9775a662410c5aff8300c8784Craig Stout ListRow rowItem = (ListRow) item; 30347520b68e50572a9775a662410c5aff8300c8784Craig Stout vh.mItemBridgeAdapter.clear(); 30447520b68e50572a9775a662410c5aff8300c8784Craig Stout vh.mItemBridgeAdapter.setAdapter(rowItem.getAdapter()); 30547520b68e50572a9775a662410c5aff8300c8784Craig Stout vh.mGridView.setAdapter(vh.mItemBridgeAdapter); 30647520b68e50572a9775a662410c5aff8300c8784Craig Stout } 30747520b68e50572a9775a662410c5aff8300c8784Craig Stout 30847520b68e50572a9775a662410c5aff8300c8784Craig Stout @Override 30947520b68e50572a9775a662410c5aff8300c8784Craig Stout public void onUnbindViewHolder(Presenter.ViewHolder holder) { 31047520b68e50572a9775a662410c5aff8300c8784Craig Stout ViewHolder vh = (ViewHolder)holder; 31147520b68e50572a9775a662410c5aff8300c8784Craig Stout vh.mGridView.setAdapter(null); 31247520b68e50572a9775a662410c5aff8300c8784Craig Stout super.onUnbindViewHolder(holder); 31347520b68e50572a9775a662410c5aff8300c8784Craig Stout } 31447520b68e50572a9775a662410c5aff8300c8784Craig Stout 315cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu /** 316cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu * ListRowPresenter overrides the default select effect of {@link RowPresenter} 317cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu * and return false. 318cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu */ 319cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu @Override 320cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu public final boolean isUsingDefaultSelectEffect() { 321cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu return false; 322cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu } 323cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu 324cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu /** 325cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu * Returns true so that default select effect is applied to each individual 326cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu * child of {@link HorizontalGridView}. Subclass may return false to disable 327cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu * the default implementation. 328cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu * @see #onSelectLevelChanged(RowPresenter.ViewHolder) 329cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu */ 330cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu public boolean isUsingDefaultListSelectEffect() { 331cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu return true; 332cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu } 333cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu 334cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu /** 335dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu * Returns true if SDK >= 18, where default shadow 336892181367d658f347d00ea5e091aa31f086b2a20Dake Gu * is applied to each individual child of {@link HorizontalGridView}. 337892181367d658f347d00ea5e091aa31f086b2a20Dake Gu * Subclass may return false to disable. 338892181367d658f347d00ea5e091aa31f086b2a20Dake Gu */ 339892181367d658f347d00ea5e091aa31f086b2a20Dake Gu public boolean isUsingDefaultShadow() { 340dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu return ShadowOverlayContainer.supportsShadow(); 341892181367d658f347d00ea5e091aa31f086b2a20Dake Gu } 342892181367d658f347d00ea5e091aa31f086b2a20Dake Gu 343892181367d658f347d00ea5e091aa31f086b2a20Dake Gu /** 344892181367d658f347d00ea5e091aa31f086b2a20Dake Gu * Enable or disable child shadow. 345892181367d658f347d00ea5e091aa31f086b2a20Dake Gu * This is not only for enable/disable default shadow implementation but also subclass must 346892181367d658f347d00ea5e091aa31f086b2a20Dake Gu * respect this flag. 347892181367d658f347d00ea5e091aa31f086b2a20Dake Gu */ 348892181367d658f347d00ea5e091aa31f086b2a20Dake Gu public final void setShadowEnabled(boolean enabled) { 349892181367d658f347d00ea5e091aa31f086b2a20Dake Gu mShadowEnabled = enabled; 350892181367d658f347d00ea5e091aa31f086b2a20Dake Gu } 351892181367d658f347d00ea5e091aa31f086b2a20Dake Gu 352892181367d658f347d00ea5e091aa31f086b2a20Dake Gu /** 353892181367d658f347d00ea5e091aa31f086b2a20Dake Gu * Returns true if child shadow is enabled. 354892181367d658f347d00ea5e091aa31f086b2a20Dake Gu * This is not only for enable/disable default shadow implementation but also subclass must 355892181367d658f347d00ea5e091aa31f086b2a20Dake Gu * respect this flag. 356892181367d658f347d00ea5e091aa31f086b2a20Dake Gu */ 357892181367d658f347d00ea5e091aa31f086b2a20Dake Gu public final boolean getShadowEnabled() { 358892181367d658f347d00ea5e091aa31f086b2a20Dake Gu return mShadowEnabled; 359892181367d658f347d00ea5e091aa31f086b2a20Dake Gu } 360892181367d658f347d00ea5e091aa31f086b2a20Dake Gu 361892181367d658f347d00ea5e091aa31f086b2a20Dake Gu final boolean needsDefaultShadow() { 362892181367d658f347d00ea5e091aa31f086b2a20Dake Gu return isUsingDefaultShadow() && getShadowEnabled(); 363892181367d658f347d00ea5e091aa31f086b2a20Dake Gu } 364892181367d658f347d00ea5e091aa31f086b2a20Dake Gu 365892181367d658f347d00ea5e091aa31f086b2a20Dake Gu @Override 366892181367d658f347d00ea5e091aa31f086b2a20Dake Gu public boolean canDrawOutOfBounds() { 367892181367d658f347d00ea5e091aa31f086b2a20Dake Gu return needsDefaultShadow(); 368892181367d658f347d00ea5e091aa31f086b2a20Dake Gu } 369892181367d658f347d00ea5e091aa31f086b2a20Dake Gu 370892181367d658f347d00ea5e091aa31f086b2a20Dake Gu /** 371cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu * Applies select level to header and draw a default color dim over each child 372cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu * of {@link HorizontalGridView}. 373cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu * <p> 374cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu * Subclass may override this method. A subclass 375cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu * needs to call super.onSelectLevelChanged() for applying header select level 376cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu * and optionally applying a default select level to each child view of 377cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu * {@link HorizontalGridView} if {@link #isUsingDefaultListSelectEffect()} 378cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu * is true. Subclass may override {@link #isUsingDefaultListSelectEffect()} to return 379cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu * false and deal with the individual item select level by itself. 380cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu * </p> 381cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu */ 382cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu @Override 383cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu protected void onSelectLevelChanged(RowPresenter.ViewHolder holder) { 384cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu super.onSelectLevelChanged(holder); 385892181367d658f347d00ea5e091aa31f086b2a20Dake Gu if (needsDefaultSelectEffect()) { 386cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu ViewHolder vh = (ViewHolder) holder; 387cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu vh.mColorDimmer.setActiveLevel(holder.mSelectLevel); 388892181367d658f347d00ea5e091aa31f086b2a20Dake Gu int dimmedColor = vh.mColorDimmer.getPaint().getColor(); 389892181367d658f347d00ea5e091aa31f086b2a20Dake Gu for (int i = 0, count = vh.mGridView.getChildCount(); i < count; i++) { 390dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu ShadowOverlayContainer wrapper = (ShadowOverlayContainer) vh.mGridView.getChildAt(i); 391dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu wrapper.setOverlayColor(dimmedColor); 392cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu } 393cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu } 394cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu } 395cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu 39647520b68e50572a9775a662410c5aff8300c8784Craig Stout} 397