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;
19f4acd3cf076435ce836a6d4a9027b73ec3050defCraig Stoutimport android.support.v17.leanback.system.Settings;
204cd4cce277571385f4d1a56d5348578c38368cbeCraig Stoutimport android.util.Log;
2160bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stoutimport android.view.KeyEvent;
2247520b68e50572a9775a662410c5aff8300c8784Craig Stoutimport android.view.View;
2347520b68e50572a9775a662410c5aff8300c8784Craig Stoutimport android.view.ViewGroup;
24892181367d658f347d00ea5e091aa31f086b2a20Dake Guimport android.view.ViewGroup.LayoutParams;
2547520b68e50572a9775a662410c5aff8300c8784Craig Stout
26bb370eee93bfe84a6e14be0e8476f48c32e2dcb0Craig Stoutimport java.util.HashMap;
27bb370eee93bfe84a6e14be0e8476f48c32e2dcb0Craig Stout
2847520b68e50572a9775a662410c5aff8300c8784Craig Stout/**
297aaa6c6ef8807cc4ea4c4642716d6e30056bc4ebDake Gu * ListRowPresenter renders {@link ListRow} using a
30cb13a318e577e14461eb008071dddf762847de42Dake Gu * {@link HorizontalGridView} hosted in a {@link ListRowView}.
317aaa6c6ef8807cc4ea4c4642716d6e30056bc4ebDake Gu *
327aaa6c6ef8807cc4ea4c4642716d6e30056bc4ebDake Gu * <h3>Hover card</h3>
3347520b68e50572a9775a662410c5aff8300c8784Craig Stout * Optionally, {@link #setHoverCardPresenterSelector(PresenterSelector)} can be used to
3447520b68e50572a9775a662410c5aff8300c8784Craig Stout * display a view for the currently focused list item below the rendered
3547520b68e50572a9775a662410c5aff8300c8784Craig Stout * list. This view is known as a hover card.
367aaa6c6ef8807cc4ea4c4642716d6e30056bc4ebDake Gu *
377aaa6c6ef8807cc4ea4c4642716d6e30056bc4ebDake Gu * <h3>Selection animation</h3>
38a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * ListRowPresenter disables {@link RowPresenter}'s default dimming effect and draws
39a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * a dim overlay on each view individually.  A subclass may override and disable
407aaa6c6ef8807cc4ea4c4642716d6e30056bc4ebDake Gu * {@link #isUsingDefaultListSelectEffect()} and write its own dim effect in
417aaa6c6ef8807cc4ea4c4642716d6e30056bc4ebDake Gu * {@link #onSelectLevelChanged(RowPresenter.ViewHolder)}.
42dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu *
43dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu * <h3>Shadow</h3>
44a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * ListRowPresenter applies a default shadow to each child view.  Call
45a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * {@link #setShadowEnabled(boolean)} to disable shadows.  A subclass may override and return
46dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu * false in {@link #isUsingDefaultShadow()} and replace with its own shadow implementation.
4747520b68e50572a9775a662410c5aff8300c8784Craig Stout */
4847520b68e50572a9775a662410c5aff8300c8784Craig Stoutpublic class ListRowPresenter extends RowPresenter {
4947520b68e50572a9775a662410c5aff8300c8784Craig Stout
5047520b68e50572a9775a662410c5aff8300c8784Craig Stout    private static final String TAG = "ListRowPresenter";
5147520b68e50572a9775a662410c5aff8300c8784Craig Stout    private static final boolean DEBUG = false;
5247520b68e50572a9775a662410c5aff8300c8784Craig Stout
53bb370eee93bfe84a6e14be0e8476f48c32e2dcb0Craig Stout    private static final int DEFAULT_RECYCLED_POOL_SIZE = 24;
54bb370eee93bfe84a6e14be0e8476f48c32e2dcb0Craig Stout
55a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout    /**
56a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout     * ViewHolder for the ListRowPresenter.
57a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout     */
5847520b68e50572a9775a662410c5aff8300c8784Craig Stout    public static class ViewHolder extends RowPresenter.ViewHolder {
5947520b68e50572a9775a662410c5aff8300c8784Craig Stout        final ListRowPresenter mListRowPresenter;
6047520b68e50572a9775a662410c5aff8300c8784Craig Stout        final HorizontalGridView mGridView;
6171fddded48048acfa744ac352166770c91a1c2b1Dake Gu        ItemBridgeAdapter mItemBridgeAdapter;
6247520b68e50572a9775a662410c5aff8300c8784Craig Stout        final HorizontalHoverCardSwitcher mHoverCardViewSwitcher = new HorizontalHoverCardSwitcher();
63e43e9266c4b7e4902fefb5d2a0cacca90a3d2681Dake Gu        final int mPaddingTop;
64e43e9266c4b7e4902fefb5d2a0cacca90a3d2681Dake Gu        final int mPaddingBottom;
65e43e9266c4b7e4902fefb5d2a0cacca90a3d2681Dake Gu        final int mPaddingLeft;
66e43e9266c4b7e4902fefb5d2a0cacca90a3d2681Dake Gu        final int mPaddingRight;
6747520b68e50572a9775a662410c5aff8300c8784Craig Stout
6847520b68e50572a9775a662410c5aff8300c8784Craig Stout        public ViewHolder(View rootView, HorizontalGridView gridView, ListRowPresenter p) {
6947520b68e50572a9775a662410c5aff8300c8784Craig Stout            super(rootView);
7047520b68e50572a9775a662410c5aff8300c8784Craig Stout            mGridView = gridView;
7147520b68e50572a9775a662410c5aff8300c8784Craig Stout            mListRowPresenter = p;
72e43e9266c4b7e4902fefb5d2a0cacca90a3d2681Dake Gu            mPaddingTop = mGridView.getPaddingTop();
73e43e9266c4b7e4902fefb5d2a0cacca90a3d2681Dake Gu            mPaddingBottom = mGridView.getPaddingBottom();
74e43e9266c4b7e4902fefb5d2a0cacca90a3d2681Dake Gu            mPaddingLeft = mGridView.getPaddingLeft();
75e43e9266c4b7e4902fefb5d2a0cacca90a3d2681Dake Gu            mPaddingRight = mGridView.getPaddingRight();
7647520b68e50572a9775a662410c5aff8300c8784Craig Stout        }
7747520b68e50572a9775a662410c5aff8300c8784Craig Stout
7847520b68e50572a9775a662410c5aff8300c8784Craig Stout        public final ListRowPresenter getListRowPresenter() {
7947520b68e50572a9775a662410c5aff8300c8784Craig Stout            return mListRowPresenter;
8047520b68e50572a9775a662410c5aff8300c8784Craig Stout        }
8147520b68e50572a9775a662410c5aff8300c8784Craig Stout
8247520b68e50572a9775a662410c5aff8300c8784Craig Stout        public final HorizontalGridView getGridView() {
8347520b68e50572a9775a662410c5aff8300c8784Craig Stout            return mGridView;
8447520b68e50572a9775a662410c5aff8300c8784Craig Stout        }
859de682083d3da5b1127969ee1fd7b74561aa9acdCraig Stout
869de682083d3da5b1127969ee1fd7b74561aa9acdCraig Stout        public final ItemBridgeAdapter getBridgeAdapter() {
879de682083d3da5b1127969ee1fd7b74561aa9acdCraig Stout            return mItemBridgeAdapter;
889de682083d3da5b1127969ee1fd7b74561aa9acdCraig Stout        }
8947520b68e50572a9775a662410c5aff8300c8784Craig Stout    }
9047520b68e50572a9775a662410c5aff8300c8784Craig Stout
9171fddded48048acfa744ac352166770c91a1c2b1Dake Gu    class ListRowPresenterItemBridgeAdapter extends ItemBridgeAdapter {
9271fddded48048acfa744ac352166770c91a1c2b1Dake Gu        ListRowPresenter.ViewHolder mRowViewHolder;
9371fddded48048acfa744ac352166770c91a1c2b1Dake Gu
9471fddded48048acfa744ac352166770c91a1c2b1Dake Gu        ListRowPresenterItemBridgeAdapter(ListRowPresenter.ViewHolder rowViewHolder) {
9571fddded48048acfa744ac352166770c91a1c2b1Dake Gu            mRowViewHolder = rowViewHolder;
9671fddded48048acfa744ac352166770c91a1c2b1Dake Gu        }
9771fddded48048acfa744ac352166770c91a1c2b1Dake Gu
9871fddded48048acfa744ac352166770c91a1c2b1Dake Gu        @Override
9971fddded48048acfa744ac352166770c91a1c2b1Dake Gu        public void onBind(final ItemBridgeAdapter.ViewHolder viewHolder) {
10071fddded48048acfa744ac352166770c91a1c2b1Dake Gu            // Only when having an OnItemClickListner, we will attach the OnClickListener.
1013a5038bd0fefa5628a31a21422bf2126c53472a9Craig Stout            if (mRowViewHolder.getOnItemViewClickedListener() != null) {
10271fddded48048acfa744ac352166770c91a1c2b1Dake Gu                viewHolder.mHolder.view.setOnClickListener(new View.OnClickListener() {
10371fddded48048acfa744ac352166770c91a1c2b1Dake Gu                    @Override
10471fddded48048acfa744ac352166770c91a1c2b1Dake Gu                    public void onClick(View v) {
10571fddded48048acfa744ac352166770c91a1c2b1Dake Gu                        ItemBridgeAdapter.ViewHolder ibh = (ItemBridgeAdapter.ViewHolder)
10671fddded48048acfa744ac352166770c91a1c2b1Dake Gu                                mRowViewHolder.mGridView.getChildViewHolder(viewHolder.itemView);
1073a5038bd0fefa5628a31a21422bf2126c53472a9Craig Stout                        if (mRowViewHolder.getOnItemViewClickedListener() != null) {
1083a5038bd0fefa5628a31a21422bf2126c53472a9Craig Stout                            mRowViewHolder.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) {
1183a5038bd0fefa5628a31a21422bf2126c53472a9Craig Stout            if (mRowViewHolder.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) {
1255870e4aca782a55d0e8f7650f06aec86080b2f88Craig Stout            if (needsDefaultListSelectEffect()) {
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;
14241ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield    private int mFocusZoomFactor;
14341ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield    private boolean mUseFocusDimmer;
144892181367d658f347d00ea5e091aa31f086b2a20Dake Gu    private boolean mShadowEnabled = true;
1459240e796bc63422c28f2707840bd99c48573279bDake Gu    private int mBrowseRowsFadingEdgeLength = -1;
1464f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout    private boolean mRoundedCornersEnabled = true;
147bb370eee93bfe84a6e14be0e8476f48c32e2dcb0Craig Stout    private HashMap<Presenter, Integer> mRecycledPoolSize = new HashMap<Presenter, Integer>();
148b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout
1494cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout    private static int sSelectedRowTopPadding;
1504cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout    private static int sExpandedSelectedRowTopPadding;
1514cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout    private static int sExpandedRowNoHovercardBottomPadding;
1524cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout
153b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout    /**
154b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout     * Constructs a ListRowPresenter with defaults.
15541ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield     * Uses {@link FocusHighlight#ZOOM_FACTOR_MEDIUM} for focus zooming and
15641ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield     * disabled dimming on focus.
157b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout     */
158b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout    public ListRowPresenter() {
159739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        this(FocusHighlight.ZOOM_FACTOR_MEDIUM);
160b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout    }
161b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout
162b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout    /**
163b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout     * Constructs a ListRowPresenter with the given parameters.
164b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout     *
16541ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield     * @param focusZoomFactor Controls the zoom factor used when an item view is focused. One of
166739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     *         {@link FocusHighlight#ZOOM_FACTOR_NONE},
167739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     *         {@link FocusHighlight#ZOOM_FACTOR_SMALL},
168575dc8a5a5c023aee0c0ec297a7d357685cf49e9Craig Stout     *         {@link FocusHighlight#ZOOM_FACTOR_XSMALL},
169739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     *         {@link FocusHighlight#ZOOM_FACTOR_MEDIUM},
170739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     *         {@link FocusHighlight#ZOOM_FACTOR_LARGE}
17141ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield     * Dimming on focus defaults to disabled.
172b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout     */
17341ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield    public ListRowPresenter(int focusZoomFactor) {
17441ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield        this(focusZoomFactor, false);
17541ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield    }
17641ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield
17741ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield    /**
17841ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield     * Constructs a ListRowPresenter with the given parameters.
17941ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield     *
18041ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield     * @param focusZoomFactor Controls the zoom factor used when an item view is focused. One of
18141ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield     *         {@link FocusHighlight#ZOOM_FACTOR_NONE},
18241ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield     *         {@link FocusHighlight#ZOOM_FACTOR_SMALL},
18341ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield     *         {@link FocusHighlight#ZOOM_FACTOR_XSMALL},
18441ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield     *         {@link FocusHighlight#ZOOM_FACTOR_MEDIUM},
18541ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield     *         {@link FocusHighlight#ZOOM_FACTOR_LARGE}
18641ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield     * @param useFocusDimmer determines if the FocusHighlighter will use the dimmer
18741ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield     */
18841ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield    public ListRowPresenter(int focusZoomFactor, boolean useFocusDimmer) {
18941ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield        if (!FocusHighlightHelper.isValidZoomIndex(focusZoomFactor)) {
190575dc8a5a5c023aee0c0ec297a7d357685cf49e9Craig Stout            throw new IllegalArgumentException("Unhandled zoom factor");
191575dc8a5a5c023aee0c0ec297a7d357685cf49e9Craig Stout        }
19241ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield        mFocusZoomFactor = focusZoomFactor;
19341ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield        mUseFocusDimmer = useFocusDimmer;
194b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout    }
195b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout
196b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout    /**
197f272f7533fcb5aba341e9ab2f4ff0421d668a8caCraig Stout     * Sets the row height for rows created by this Presenter. Rows
198a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn     * created before calling this method will not be updated.
199a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn     *
200f272f7533fcb5aba341e9ab2f4ff0421d668a8caCraig Stout     * @param rowHeight Row height in pixels, or WRAP_CONTENT, or 0
201f272f7533fcb5aba341e9ab2f4ff0421d668a8caCraig Stout     * to use the default height.
202a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn     */
203a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn    public void setRowHeight(int rowHeight) {
204a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn        mRowHeight = rowHeight;
205a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn    }
206a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn
207a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn    /**
208f272f7533fcb5aba341e9ab2f4ff0421d668a8caCraig Stout     * Returns the row height for list rows created by this Presenter.
209a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn     */
210a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn    public int getRowHeight() {
211a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn        return mRowHeight;
212a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn    }
213a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn
214a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn    /**
215f272f7533fcb5aba341e9ab2f4ff0421d668a8caCraig Stout     * Sets the expanded row height for rows created by this Presenter.
216f272f7533fcb5aba341e9ab2f4ff0421d668a8caCraig Stout     * If not set, expanded rows have the same height as unexpanded
217a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn     * rows.
218a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn     *
219f272f7533fcb5aba341e9ab2f4ff0421d668a8caCraig Stout     * @param rowHeight The row height in to use when the row is expanded,
220f272f7533fcb5aba341e9ab2f4ff0421d668a8caCraig Stout     *        in pixels, or WRAP_CONTENT, or 0 to use the default.
221a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn     */
222a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn    public void setExpandedRowHeight(int rowHeight) {
223a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn        mExpandedRowHeight = rowHeight;
224a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn    }
225a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn
226a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn    /**
227f272f7533fcb5aba341e9ab2f4ff0421d668a8caCraig Stout     * Returns the expanded row height for rows created by this Presenter.
228a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn     */
229a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn    public int getExpandedRowHeight() {
230f272f7533fcb5aba341e9ab2f4ff0421d668a8caCraig Stout        return mExpandedRowHeight != 0 ? mExpandedRowHeight : mRowHeight;
231a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn    }
232a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn
233a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn    /**
234b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout     * Returns the zoom factor used for focus highlighting.
235b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout     */
23641ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield    public final int getFocusZoomFactor() {
23741ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield        return mFocusZoomFactor;
23841ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield    }
239a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout
24041ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield    /**
24141ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield     * Returns the zoom factor used for focus highlighting.
24241ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield     * @deprecated use {@link #getFocusZoomFactor} instead.
24341ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield     */
244a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout    @Deprecated
245a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout    public final int getZoomFactor() {
24641ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield        return mFocusZoomFactor;
24741ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield    }
24841ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield
24941ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield    /**
25041ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield     * Returns true if the focus dimmer is used for focus highlighting; false otherwise.
25141ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield     */
25241ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield    public final boolean isFocusDimmerUsed() {
25341ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield        return mUseFocusDimmer;
254b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout    }
25547520b68e50572a9775a662410c5aff8300c8784Craig Stout
256892181367d658f347d00ea5e091aa31f086b2a20Dake Gu    private ItemBridgeAdapter.Wrapper mCardWrapper = new ItemBridgeAdapter.Wrapper() {
257892181367d658f347d00ea5e091aa31f086b2a20Dake Gu        @Override
258892181367d658f347d00ea5e091aa31f086b2a20Dake Gu        public View createWrapper(View root) {
259dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu            ShadowOverlayContainer wrapper = new ShadowOverlayContainer(root.getContext());
260892181367d658f347d00ea5e091aa31f086b2a20Dake Gu            wrapper.setLayoutParams(
261892181367d658f347d00ea5e091aa31f086b2a20Dake Gu                    new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
262f4acd3cf076435ce836a6d4a9027b73ec3050defCraig Stout            if (isUsingZOrder(root.getContext())) {
263f4acd3cf076435ce836a6d4a9027b73ec3050defCraig Stout                wrapper.useDynamicShadow();
264f4acd3cf076435ce836a6d4a9027b73ec3050defCraig Stout            } else {
265f4acd3cf076435ce836a6d4a9027b73ec3050defCraig Stout                wrapper.useStaticShadow();
266f4acd3cf076435ce836a6d4a9027b73ec3050defCraig Stout            }
2674f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout            wrapper.initialize(needsDefaultShadow(),
2684f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout                    needsDefaultListSelectEffect(),
2694f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout                    areChildRoundedCornersEnabled());
270892181367d658f347d00ea5e091aa31f086b2a20Dake Gu            return wrapper;
271892181367d658f347d00ea5e091aa31f086b2a20Dake Gu        }
272892181367d658f347d00ea5e091aa31f086b2a20Dake Gu        @Override
273892181367d658f347d00ea5e091aa31f086b2a20Dake Gu        public void wrap(View wrapper, View wrapped) {
274dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu            ((ShadowOverlayContainer) wrapper).wrap(wrapped);
275892181367d658f347d00ea5e091aa31f086b2a20Dake Gu        }
276892181367d658f347d00ea5e091aa31f086b2a20Dake Gu    };
277892181367d658f347d00ea5e091aa31f086b2a20Dake Gu
27847520b68e50572a9775a662410c5aff8300c8784Craig Stout    @Override
27947520b68e50572a9775a662410c5aff8300c8784Craig Stout    protected void initializeRowViewHolder(RowPresenter.ViewHolder holder) {
28047520b68e50572a9775a662410c5aff8300c8784Craig Stout        super.initializeRowViewHolder(holder);
28147520b68e50572a9775a662410c5aff8300c8784Craig Stout        final ViewHolder rowViewHolder = (ViewHolder) holder;
28271fddded48048acfa744ac352166770c91a1c2b1Dake Gu        rowViewHolder.mItemBridgeAdapter = new ListRowPresenterItemBridgeAdapter(rowViewHolder);
2834f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout        if (needsDefaultListSelectEffect() || needsDefaultShadow()
2844f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout                || areChildRoundedCornersEnabled()) {
285892181367d658f347d00ea5e091aa31f086b2a20Dake Gu            rowViewHolder.mItemBridgeAdapter.setWrapper(mCardWrapper);
286892181367d658f347d00ea5e091aa31f086b2a20Dake Gu        }
2875870e4aca782a55d0e8f7650f06aec86080b2f88Craig Stout        if (needsDefaultShadow()) {
288dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu            ShadowOverlayContainer.prepareParentForShadow(rowViewHolder.mGridView);
289cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu        }
29046e7de54775fc37dc51041629c79249e6dae3242Dake Gu        FocusHighlightHelper.setupBrowseItemFocusHighlight(rowViewHolder.mItemBridgeAdapter,
29141ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield                mFocusZoomFactor, mUseFocusDimmer);
292f4acd3cf076435ce836a6d4a9027b73ec3050defCraig Stout        rowViewHolder.mGridView.setFocusDrawingOrderEnabled(
293f4acd3cf076435ce836a6d4a9027b73ec3050defCraig Stout                !isUsingZOrder(rowViewHolder.getGridView().getContext()));
29447520b68e50572a9775a662410c5aff8300c8784Craig Stout        rowViewHolder.mGridView.setOnChildSelectedListener(
29547520b68e50572a9775a662410c5aff8300c8784Craig Stout                new OnChildSelectedListener() {
29647520b68e50572a9775a662410c5aff8300c8784Craig Stout            @Override
29747520b68e50572a9775a662410c5aff8300c8784Craig Stout            public void onChildSelected(ViewGroup parent, View view, int position, long id) {
2980246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                selectChildView(rowViewHolder, view, true);
29947520b68e50572a9775a662410c5aff8300c8784Craig Stout            }
30047520b68e50572a9775a662410c5aff8300c8784Craig Stout        });
30160bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout        rowViewHolder.mGridView.setOnUnhandledKeyListener(
30260bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout                new BaseGridView.OnUnhandledKeyListener() {
30360bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout            @Override
30460bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout            public boolean onUnhandledKey(KeyEvent event) {
30560bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout                if (rowViewHolder.getOnKeyListener() != null &&
30660bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout                        rowViewHolder.getOnKeyListener().onKey(
30760bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout                                rowViewHolder.view, event.getKeyCode(), event)) {
30860bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout                    return true;
30960bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout                }
31060bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout                return false;
31147520b68e50572a9775a662410c5aff8300c8784Craig Stout            }
31247520b68e50572a9775a662410c5aff8300c8784Craig Stout        });
31347520b68e50572a9775a662410c5aff8300c8784Craig Stout    }
31447520b68e50572a9775a662410c5aff8300c8784Craig Stout
315cb13a318e577e14461eb008071dddf762847de42Dake Gu    final boolean needsDefaultListSelectEffect() {
316cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu        return isUsingDefaultListSelectEffect() && getSelectEffectEnabled();
317cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu    }
318cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu
31947520b68e50572a9775a662410c5aff8300c8784Craig Stout    /**
320bb370eee93bfe84a6e14be0e8476f48c32e2dcb0Craig Stout     * Sets the recycled pool size for the given presenter.
321bb370eee93bfe84a6e14be0e8476f48c32e2dcb0Craig Stout     */
322bb370eee93bfe84a6e14be0e8476f48c32e2dcb0Craig Stout    public void setRecycledPoolSize(Presenter presenter, int size) {
323bb370eee93bfe84a6e14be0e8476f48c32e2dcb0Craig Stout        mRecycledPoolSize.put(presenter, size);
324bb370eee93bfe84a6e14be0e8476f48c32e2dcb0Craig Stout    }
325bb370eee93bfe84a6e14be0e8476f48c32e2dcb0Craig Stout
326bb370eee93bfe84a6e14be0e8476f48c32e2dcb0Craig Stout    /**
327bb370eee93bfe84a6e14be0e8476f48c32e2dcb0Craig Stout     * Returns the recycled pool size for the given presenter.
328bb370eee93bfe84a6e14be0e8476f48c32e2dcb0Craig Stout     */
329bb370eee93bfe84a6e14be0e8476f48c32e2dcb0Craig Stout    public int getRecycledPoolSize(Presenter presenter) {
330bb370eee93bfe84a6e14be0e8476f48c32e2dcb0Craig Stout        return mRecycledPoolSize.containsKey(presenter) ? mRecycledPoolSize.get(presenter) :
331bb370eee93bfe84a6e14be0e8476f48c32e2dcb0Craig Stout                DEFAULT_RECYCLED_POOL_SIZE;
332bb370eee93bfe84a6e14be0e8476f48c32e2dcb0Craig Stout    }
333bb370eee93bfe84a6e14be0e8476f48c32e2dcb0Craig Stout
334bb370eee93bfe84a6e14be0e8476f48c32e2dcb0Craig Stout    /**
335a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout     * Sets the {@link PresenterSelector} used for showing a select object in a hover card.
33647520b68e50572a9775a662410c5aff8300c8784Craig Stout     */
33747520b68e50572a9775a662410c5aff8300c8784Craig Stout    public final void setHoverCardPresenterSelector(PresenterSelector selector) {
33847520b68e50572a9775a662410c5aff8300c8784Craig Stout        mHoverCardPresenterSelector = selector;
33947520b68e50572a9775a662410c5aff8300c8784Craig Stout    }
34047520b68e50572a9775a662410c5aff8300c8784Craig Stout
34147520b68e50572a9775a662410c5aff8300c8784Craig Stout    /**
342a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout     * Returns the {@link PresenterSelector} used for showing a select object in a hover card.
34347520b68e50572a9775a662410c5aff8300c8784Craig Stout     */
34447520b68e50572a9775a662410c5aff8300c8784Craig Stout    public final PresenterSelector getHoverCardPresenterSelector() {
34547520b68e50572a9775a662410c5aff8300c8784Craig Stout        return mHoverCardPresenterSelector;
34647520b68e50572a9775a662410c5aff8300c8784Craig Stout    }
34747520b68e50572a9775a662410c5aff8300c8784Craig Stout
34847520b68e50572a9775a662410c5aff8300c8784Craig Stout    /*
34947520b68e50572a9775a662410c5aff8300c8784Craig Stout     * Perform operations when a child of horizontal grid view is selected.
35047520b68e50572a9775a662410c5aff8300c8784Craig Stout     */
3510246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    private void selectChildView(ViewHolder rowViewHolder, View view, boolean fireEvent) {
35247520b68e50572a9775a662410c5aff8300c8784Craig Stout        if (view != null) {
3533173fdc69a928880a271036570c235f874b86f65butterfield@google.com            if (rowViewHolder.mExpanded && rowViewHolder.mSelected) {
3543173fdc69a928880a271036570c235f874b86f65butterfield@google.com                ItemBridgeAdapter.ViewHolder ibh = (ItemBridgeAdapter.ViewHolder)
3553173fdc69a928880a271036570c235f874b86f65butterfield@google.com                        rowViewHolder.mGridView.getChildViewHolder(view);
3563173fdc69a928880a271036570c235f874b86f65butterfield@google.com
3573173fdc69a928880a271036570c235f874b86f65butterfield@google.com                if (mHoverCardPresenterSelector != null) {
3583a5038bd0fefa5628a31a21422bf2126c53472a9Craig Stout                    rowViewHolder.mHoverCardViewSwitcher.select(
3593a5038bd0fefa5628a31a21422bf2126c53472a9Craig Stout                            rowViewHolder.mGridView, view, ibh.mItem);
3603173fdc69a928880a271036570c235f874b86f65butterfield@google.com                }
3610246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                if (fireEvent && rowViewHolder.getOnItemViewSelectedListener() != null) {
3623a5038bd0fefa5628a31a21422bf2126c53472a9Craig Stout                    rowViewHolder.getOnItemViewSelectedListener().onItemSelected(
3633a5038bd0fefa5628a31a21422bf2126c53472a9Craig Stout                            ibh.mHolder, ibh.mItem, rowViewHolder, rowViewHolder.mRow);
3643173fdc69a928880a271036570c235f874b86f65butterfield@google.com                }
3653173fdc69a928880a271036570c235f874b86f65butterfield@google.com            }
3663173fdc69a928880a271036570c235f874b86f65butterfield@google.com        } else {
36747520b68e50572a9775a662410c5aff8300c8784Craig Stout            if (mHoverCardPresenterSelector != null) {
36847520b68e50572a9775a662410c5aff8300c8784Craig Stout                rowViewHolder.mHoverCardViewSwitcher.unselect();
36947520b68e50572a9775a662410c5aff8300c8784Craig Stout            }
3700246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            if (fireEvent && rowViewHolder.getOnItemViewSelectedListener() != null) {
3713a5038bd0fefa5628a31a21422bf2126c53472a9Craig Stout                rowViewHolder.getOnItemViewSelectedListener().onItemSelected(
3723a5038bd0fefa5628a31a21422bf2126c53472a9Craig Stout                        null, null, rowViewHolder, rowViewHolder.mRow);
3739de363b8db05106b03d115c266859fe200d41db7Dake Gu            }
37447520b68e50572a9775a662410c5aff8300c8784Craig Stout        }
37547520b68e50572a9775a662410c5aff8300c8784Craig Stout    }
37647520b68e50572a9775a662410c5aff8300c8784Craig Stout
3774cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout    private static void initStatics(Context context) {
3784cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout        if (sSelectedRowTopPadding == 0) {
3794cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout            sSelectedRowTopPadding = context.getResources().getDimensionPixelSize(
3804cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout                    R.dimen.lb_browse_selected_row_top_padding);
3814cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout            sExpandedSelectedRowTopPadding = context.getResources().getDimensionPixelSize(
3824cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout                    R.dimen.lb_browse_expanded_selected_row_top_padding);
3834cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout            sExpandedRowNoHovercardBottomPadding = context.getResources().getDimensionPixelSize(
3844cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout                    R.dimen.lb_browse_expanded_row_no_hovercard_bottom_padding);
3854cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout        }
3864cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout    }
3874cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout
3884cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout    private int getSpaceUnderBaseline(ListRowPresenter.ViewHolder vh) {
3894cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout        RowHeaderPresenter.ViewHolder headerViewHolder = vh.getHeaderViewHolder();
3904cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout        if (headerViewHolder != null) {
3914cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout            if (getHeaderPresenter() != null) {
3924cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout                return getHeaderPresenter().getSpaceUnderBaseline(headerViewHolder);
3934cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout            }
3944cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout            return headerViewHolder.view.getPaddingBottom();
3954cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout        }
3964cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout        return 0;
3974cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout    }
3984cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout
3994cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout    private void setVerticalPadding(ListRowPresenter.ViewHolder vh) {
4004cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout        int paddingTop, paddingBottom;
4013146269a82645438b55a41c679047e3be36e65dfCraig Stout        // Note: sufficient bottom padding needed for card shadows.
4024cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout        if (vh.isExpanded()) {
4034cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout            int headerSpaceUnderBaseline = getSpaceUnderBaseline(vh);
4044cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout            if (DEBUG) Log.v(TAG, "headerSpaceUnderBaseline " + headerSpaceUnderBaseline);
4054cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout            paddingTop = (vh.isSelected() ? sExpandedSelectedRowTopPadding : vh.mPaddingTop) -
4064cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout                    headerSpaceUnderBaseline;
4074cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout            paddingBottom = mHoverCardPresenterSelector == null ?
4084cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout                    sExpandedRowNoHovercardBottomPadding : vh.mPaddingBottom;
4094cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout        } else if (vh.isSelected()) {
4103146269a82645438b55a41c679047e3be36e65dfCraig Stout            paddingTop = sSelectedRowTopPadding - vh.mPaddingBottom;
4113146269a82645438b55a41c679047e3be36e65dfCraig Stout            paddingBottom = sSelectedRowTopPadding;
4124cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout        } else {
4133146269a82645438b55a41c679047e3be36e65dfCraig Stout            paddingTop = 0;
4143146269a82645438b55a41c679047e3be36e65dfCraig Stout            paddingBottom = vh.mPaddingBottom;
4154cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout        }
4164cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout        vh.getGridView().setPadding(vh.mPaddingLeft, paddingTop, vh.mPaddingRight,
4174cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout                paddingBottom);
4184cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout    }
4194cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout
42047520b68e50572a9775a662410c5aff8300c8784Craig Stout    @Override
42147520b68e50572a9775a662410c5aff8300c8784Craig Stout    protected RowPresenter.ViewHolder createRowViewHolder(ViewGroup parent) {
4224cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout        initStatics(parent.getContext());
423cb13a318e577e14461eb008071dddf762847de42Dake Gu        ListRowView rowView = new ListRowView(parent.getContext());
4249240e796bc63422c28f2707840bd99c48573279bDake Gu        setupFadingEffect(rowView);
425f272f7533fcb5aba341e9ab2f4ff0421d668a8caCraig Stout        if (mRowHeight != 0) {
426a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn            rowView.getGridView().setRowHeight(mRowHeight);
427a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn        }
42847520b68e50572a9775a662410c5aff8300c8784Craig Stout        return new ViewHolder(rowView, rowView.getGridView(), this);
42947520b68e50572a9775a662410c5aff8300c8784Craig Stout    }
43047520b68e50572a9775a662410c5aff8300c8784Craig Stout
431cb04695965b44b6ff633a773426df286d3bfaad9John Butterfield    /**
432cb04695965b44b6ff633a773426df286d3bfaad9John Butterfield     * Dispatch item selected event using current selected item in the {@link HorizontalGridView}.
433cb04695965b44b6ff633a773426df286d3bfaad9John Butterfield     * The method should only be called from onRowViewSelected().
434cb04695965b44b6ff633a773426df286d3bfaad9John Butterfield     */
435cb04695965b44b6ff633a773426df286d3bfaad9John Butterfield    @Override
436cb04695965b44b6ff633a773426df286d3bfaad9John Butterfield    protected void dispatchItemSelectedListener(RowPresenter.ViewHolder holder, boolean selected) {
437cb04695965b44b6ff633a773426df286d3bfaad9John Butterfield        ViewHolder vh = (ViewHolder)holder;
438cb04695965b44b6ff633a773426df286d3bfaad9John Butterfield        ItemBridgeAdapter.ViewHolder itemViewHolder = (ItemBridgeAdapter.ViewHolder)
439cb04695965b44b6ff633a773426df286d3bfaad9John Butterfield                vh.mGridView.findViewHolderForPosition(vh.mGridView.getSelectedPosition());
440cb04695965b44b6ff633a773426df286d3bfaad9John Butterfield        if (itemViewHolder == null) {
441cb04695965b44b6ff633a773426df286d3bfaad9John Butterfield            super.dispatchItemSelectedListener(holder, selected);
442cb04695965b44b6ff633a773426df286d3bfaad9John Butterfield            return;
443cb04695965b44b6ff633a773426df286d3bfaad9John Butterfield        }
444cb04695965b44b6ff633a773426df286d3bfaad9John Butterfield
445cb04695965b44b6ff633a773426df286d3bfaad9John Butterfield        if (selected) {
4463a5038bd0fefa5628a31a21422bf2126c53472a9Craig Stout            if (holder.getOnItemViewSelectedListener() != null) {
4473a5038bd0fefa5628a31a21422bf2126c53472a9Craig Stout                holder.getOnItemViewSelectedListener().onItemSelected(
448cb04695965b44b6ff633a773426df286d3bfaad9John Butterfield                        itemViewHolder.getViewHolder(), itemViewHolder.mItem, vh, vh.getRow());
449cb04695965b44b6ff633a773426df286d3bfaad9John Butterfield            }
450cb04695965b44b6ff633a773426df286d3bfaad9John Butterfield        }
451cb04695965b44b6ff633a773426df286d3bfaad9John Butterfield    }
452cb04695965b44b6ff633a773426df286d3bfaad9John Butterfield
45347520b68e50572a9775a662410c5aff8300c8784Craig Stout    @Override
45447520b68e50572a9775a662410c5aff8300c8784Craig Stout    protected void onRowViewSelected(RowPresenter.ViewHolder holder, boolean selected) {
4552f97594742886d045ca1ce409ebc6e6e780452f6Dake Gu        super.onRowViewSelected(holder, selected);
4564cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout        ViewHolder vh = (ViewHolder) holder;
4574cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout        setVerticalPadding(vh);
4584cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout        updateFooterViewSwitcher(vh);
45947520b68e50572a9775a662410c5aff8300c8784Craig Stout    }
46047520b68e50572a9775a662410c5aff8300c8784Craig Stout
46147520b68e50572a9775a662410c5aff8300c8784Craig Stout    /*
46247520b68e50572a9775a662410c5aff8300c8784Craig Stout     * Show or hide hover card when row selection or expanded state is changed.
46347520b68e50572a9775a662410c5aff8300c8784Craig Stout     */
46447520b68e50572a9775a662410c5aff8300c8784Craig Stout    private void updateFooterViewSwitcher(ViewHolder vh) {
46547520b68e50572a9775a662410c5aff8300c8784Craig Stout        if (vh.mExpanded && vh.mSelected) {
46647520b68e50572a9775a662410c5aff8300c8784Craig Stout            if (mHoverCardPresenterSelector != null) {
46747520b68e50572a9775a662410c5aff8300c8784Craig Stout                vh.mHoverCardViewSwitcher.init((ViewGroup) vh.view,
46847520b68e50572a9775a662410c5aff8300c8784Craig Stout                        mHoverCardPresenterSelector);
46947520b68e50572a9775a662410c5aff8300c8784Craig Stout            }
47002e411c2c69d20aab138f1a162a24ea650eff7a1Dake Gu            ItemBridgeAdapter.ViewHolder ibh = (ItemBridgeAdapter.ViewHolder)
47102e411c2c69d20aab138f1a162a24ea650eff7a1Dake Gu                    vh.mGridView.findViewHolderForPosition(
47202e411c2c69d20aab138f1a162a24ea650eff7a1Dake Gu                            vh.mGridView.getSelectedPosition());
4730246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            selectChildView(vh, ibh == null ? null : ibh.itemView, false);
47447520b68e50572a9775a662410c5aff8300c8784Craig Stout        } else {
47547520b68e50572a9775a662410c5aff8300c8784Craig Stout            if (mHoverCardPresenterSelector != null) {
4762f97594742886d045ca1ce409ebc6e6e780452f6Dake Gu                vh.mHoverCardViewSwitcher.unselect();
47747520b68e50572a9775a662410c5aff8300c8784Craig Stout            }
47847520b68e50572a9775a662410c5aff8300c8784Craig Stout        }
47947520b68e50572a9775a662410c5aff8300c8784Craig Stout    }
48047520b68e50572a9775a662410c5aff8300c8784Craig Stout
4819240e796bc63422c28f2707840bd99c48573279bDake Gu    private void setupFadingEffect(ListRowView rowView) {
4829240e796bc63422c28f2707840bd99c48573279bDake Gu        // content is completely faded at 1/2 padding of left, fading length is 1/2 of padding.
4839240e796bc63422c28f2707840bd99c48573279bDake Gu        HorizontalGridView gridView = rowView.getGridView();
4849240e796bc63422c28f2707840bd99c48573279bDake Gu        if (mBrowseRowsFadingEdgeLength < 0) {
4859240e796bc63422c28f2707840bd99c48573279bDake Gu            TypedArray ta = gridView.getContext()
4869240e796bc63422c28f2707840bd99c48573279bDake Gu                    .obtainStyledAttributes(R.styleable.LeanbackTheme);
4879240e796bc63422c28f2707840bd99c48573279bDake Gu            mBrowseRowsFadingEdgeLength = (int) ta.getDimension(
4889240e796bc63422c28f2707840bd99c48573279bDake Gu                    R.styleable.LeanbackTheme_browseRowsFadingEdgeLength, 0);
4899240e796bc63422c28f2707840bd99c48573279bDake Gu            ta.recycle();
49047520b68e50572a9775a662410c5aff8300c8784Craig Stout        }
4919240e796bc63422c28f2707840bd99c48573279bDake Gu        gridView.setFadingLeftEdgeLength(mBrowseRowsFadingEdgeLength);
49247520b68e50572a9775a662410c5aff8300c8784Craig Stout    }
49347520b68e50572a9775a662410c5aff8300c8784Craig Stout
49447520b68e50572a9775a662410c5aff8300c8784Craig Stout    @Override
49547520b68e50572a9775a662410c5aff8300c8784Craig Stout    protected void onRowViewExpanded(RowPresenter.ViewHolder holder, boolean expanded) {
49647520b68e50572a9775a662410c5aff8300c8784Craig Stout        super.onRowViewExpanded(holder, expanded);
49747520b68e50572a9775a662410c5aff8300c8784Craig Stout        ViewHolder vh = (ViewHolder) holder;
498a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn        if (getRowHeight() != getExpandedRowHeight()) {
499a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn            int newHeight = expanded ? getExpandedRowHeight() : getRowHeight();
500a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn            vh.getGridView().setRowHeight(newHeight);
501a4560456facaa3dd341a7ab2f372f655d46f7ee6Tim Kilbourn        }
5024cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout        setVerticalPadding(vh);
50347520b68e50572a9775a662410c5aff8300c8784Craig Stout        updateFooterViewSwitcher(vh);
50447520b68e50572a9775a662410c5aff8300c8784Craig Stout    }
50547520b68e50572a9775a662410c5aff8300c8784Craig Stout
50647520b68e50572a9775a662410c5aff8300c8784Craig Stout    @Override
507cb13a318e577e14461eb008071dddf762847de42Dake Gu    protected void onBindRowViewHolder(RowPresenter.ViewHolder holder, Object item) {
508cb13a318e577e14461eb008071dddf762847de42Dake Gu        super.onBindRowViewHolder(holder, item);
509cb13a318e577e14461eb008071dddf762847de42Dake Gu        ViewHolder vh = (ViewHolder) holder;
51047520b68e50572a9775a662410c5aff8300c8784Craig Stout        ListRow rowItem = (ListRow) item;
51147520b68e50572a9775a662410c5aff8300c8784Craig Stout        vh.mItemBridgeAdapter.setAdapter(rowItem.getAdapter());
51247520b68e50572a9775a662410c5aff8300c8784Craig Stout        vh.mGridView.setAdapter(vh.mItemBridgeAdapter);
51347520b68e50572a9775a662410c5aff8300c8784Craig Stout    }
51447520b68e50572a9775a662410c5aff8300c8784Craig Stout
51547520b68e50572a9775a662410c5aff8300c8784Craig Stout    @Override
516cb13a318e577e14461eb008071dddf762847de42Dake Gu    protected void onUnbindRowViewHolder(RowPresenter.ViewHolder holder) {
5175358b0ca6ed795892bd097fdf15d41fb6b1a03d2Craig Stout        ViewHolder vh = (ViewHolder) holder;
5185358b0ca6ed795892bd097fdf15d41fb6b1a03d2Craig Stout        vh.mGridView.setAdapter(null);
5195358b0ca6ed795892bd097fdf15d41fb6b1a03d2Craig Stout        vh.mItemBridgeAdapter.clear();
520cb13a318e577e14461eb008071dddf762847de42Dake Gu        super.onUnbindRowViewHolder(holder);
52147520b68e50572a9775a662410c5aff8300c8784Craig Stout    }
52247520b68e50572a9775a662410c5aff8300c8784Craig Stout
523cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu    /**
524cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu     * ListRowPresenter overrides the default select effect of {@link RowPresenter}
525cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu     * and return false.
526cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu     */
527cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu    @Override
528cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu    public final boolean isUsingDefaultSelectEffect() {
529cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu        return false;
530cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu    }
531cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu
532cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu    /**
533cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu     * Returns true so that default select effect is applied to each individual
534cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu     * child of {@link HorizontalGridView}.  Subclass may return false to disable
535cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu     * the default implementation.
536cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu     * @see #onSelectLevelChanged(RowPresenter.ViewHolder)
537cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu     */
538cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu    public boolean isUsingDefaultListSelectEffect() {
539cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu        return true;
540cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu    }
541cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu
542cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu    /**
543dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu     * Returns true if SDK >= 18, where default shadow
544892181367d658f347d00ea5e091aa31f086b2a20Dake Gu     * is applied to each individual child of {@link HorizontalGridView}.
545892181367d658f347d00ea5e091aa31f086b2a20Dake Gu     * Subclass may return false to disable.
546892181367d658f347d00ea5e091aa31f086b2a20Dake Gu     */
547892181367d658f347d00ea5e091aa31f086b2a20Dake Gu    public boolean isUsingDefaultShadow() {
548dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu        return ShadowOverlayContainer.supportsShadow();
549892181367d658f347d00ea5e091aa31f086b2a20Dake Gu    }
550892181367d658f347d00ea5e091aa31f086b2a20Dake Gu
551892181367d658f347d00ea5e091aa31f086b2a20Dake Gu    /**
5520fcad32410ad29031630bb9cc2da35d33a4aa906Dake Gu     * Returns true if SDK >= L, where Z shadow is enabled so that Z order is enabled
5530fcad32410ad29031630bb9cc2da35d33a4aa906Dake Gu     * on each child of horizontal list.   If subclass returns false in isUsingDefaultShadow()
5540fcad32410ad29031630bb9cc2da35d33a4aa906Dake Gu     * and does not use Z-shadow on SDK >= L, it should override isUsingZOrder() return false.
5550fcad32410ad29031630bb9cc2da35d33a4aa906Dake Gu     */
556f4acd3cf076435ce836a6d4a9027b73ec3050defCraig Stout    public boolean isUsingZOrder(Context context) {
557f4acd3cf076435ce836a6d4a9027b73ec3050defCraig Stout        return ShadowOverlayContainer.supportsDynamicShadow() &&
558f4acd3cf076435ce836a6d4a9027b73ec3050defCraig Stout                !Settings.getInstance(context).preferStaticShadows();
5590fcad32410ad29031630bb9cc2da35d33a4aa906Dake Gu    }
5600fcad32410ad29031630bb9cc2da35d33a4aa906Dake Gu
5610fcad32410ad29031630bb9cc2da35d33a4aa906Dake Gu    /**
562a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout     * Enables or disables child shadow.
563892181367d658f347d00ea5e091aa31f086b2a20Dake Gu     * This is not only for enable/disable default shadow implementation but also subclass must
564892181367d658f347d00ea5e091aa31f086b2a20Dake Gu     * respect this flag.
565892181367d658f347d00ea5e091aa31f086b2a20Dake Gu     */
566892181367d658f347d00ea5e091aa31f086b2a20Dake Gu    public final void setShadowEnabled(boolean enabled) {
567892181367d658f347d00ea5e091aa31f086b2a20Dake Gu        mShadowEnabled = enabled;
568892181367d658f347d00ea5e091aa31f086b2a20Dake Gu    }
569892181367d658f347d00ea5e091aa31f086b2a20Dake Gu
570892181367d658f347d00ea5e091aa31f086b2a20Dake Gu    /**
571892181367d658f347d00ea5e091aa31f086b2a20Dake Gu     * Returns true if child shadow is enabled.
572892181367d658f347d00ea5e091aa31f086b2a20Dake Gu     * This is not only for enable/disable default shadow implementation but also subclass must
573892181367d658f347d00ea5e091aa31f086b2a20Dake Gu     * respect this flag.
574892181367d658f347d00ea5e091aa31f086b2a20Dake Gu     */
575892181367d658f347d00ea5e091aa31f086b2a20Dake Gu    public final boolean getShadowEnabled() {
576892181367d658f347d00ea5e091aa31f086b2a20Dake Gu        return mShadowEnabled;
577892181367d658f347d00ea5e091aa31f086b2a20Dake Gu    }
578892181367d658f347d00ea5e091aa31f086b2a20Dake Gu
5794f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout    /**
5804f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout     * Enables or disabled rounded corners on children of this row.
5814f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout     * Supported on Android SDK >= L.
5824f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout     */
5834f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout    public final void enableChildRoundedCorners(boolean enable) {
5844f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout        mRoundedCornersEnabled = enable;
5854f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout    }
5864f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout
5874f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout    /**
5884f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout     * Returns true if rounded corners are enabled for children of this row.
5894f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout     */
5904f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout    public final boolean areChildRoundedCornersEnabled() {
5914f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout        return mRoundedCornersEnabled;
5924f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout    }
5934f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout
594892181367d658f347d00ea5e091aa31f086b2a20Dake Gu    final boolean needsDefaultShadow() {
595892181367d658f347d00ea5e091aa31f086b2a20Dake Gu        return isUsingDefaultShadow() && getShadowEnabled();
596892181367d658f347d00ea5e091aa31f086b2a20Dake Gu    }
597892181367d658f347d00ea5e091aa31f086b2a20Dake Gu
598892181367d658f347d00ea5e091aa31f086b2a20Dake Gu    @Override
599892181367d658f347d00ea5e091aa31f086b2a20Dake Gu    public boolean canDrawOutOfBounds() {
600892181367d658f347d00ea5e091aa31f086b2a20Dake Gu        return needsDefaultShadow();
601892181367d658f347d00ea5e091aa31f086b2a20Dake Gu    }
602892181367d658f347d00ea5e091aa31f086b2a20Dake Gu
603892181367d658f347d00ea5e091aa31f086b2a20Dake Gu    /**
604cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu     * Applies select level to header and draw a default color dim over each child
605cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu     * of {@link HorizontalGridView}.
606cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu     * <p>
607cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu     * Subclass may override this method.  A subclass
608cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu     * needs to call super.onSelectLevelChanged() for applying header select level
609cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu     * and optionally applying a default select level to each child view of
610cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu     * {@link HorizontalGridView} if {@link #isUsingDefaultListSelectEffect()}
611cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu     * is true.  Subclass may override {@link #isUsingDefaultListSelectEffect()} to return
612cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu     * false and deal with the individual item select level by itself.
613cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu     * </p>
614cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu     */
615cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu    @Override
616cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu    protected void onSelectLevelChanged(RowPresenter.ViewHolder holder) {
617cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu        super.onSelectLevelChanged(holder);
618cb13a318e577e14461eb008071dddf762847de42Dake Gu        if (needsDefaultListSelectEffect()) {
619cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu            ViewHolder vh = (ViewHolder) holder;
620892181367d658f347d00ea5e091aa31f086b2a20Dake Gu            int dimmedColor = vh.mColorDimmer.getPaint().getColor();
621892181367d658f347d00ea5e091aa31f086b2a20Dake Gu            for (int i = 0, count = vh.mGridView.getChildCount(); i < count; i++) {
622dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu                ShadowOverlayContainer wrapper = (ShadowOverlayContainer) vh.mGridView.getChildAt(i);
623dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu                wrapper.setOverlayColor(dimmedColor);
624cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu            }
6259240e796bc63422c28f2707840bd99c48573279bDake Gu            if (vh.mGridView.getFadingLeftEdge()) {
6269240e796bc63422c28f2707840bd99c48573279bDake Gu                vh.mGridView.invalidate();
6279240e796bc63422c28f2707840bd99c48573279bDake Gu            }
628cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu        }
629cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu    }
630cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu
631709bb7083a089e788d84ffa81f2c4f60a1bc8cf2Dake Gu    @Override
632709bb7083a089e788d84ffa81f2c4f60a1bc8cf2Dake Gu    public void freeze(RowPresenter.ViewHolder holder, boolean freeze) {
633709bb7083a089e788d84ffa81f2c4f60a1bc8cf2Dake Gu        ViewHolder vh = (ViewHolder) holder;
634709bb7083a089e788d84ffa81f2c4f60a1bc8cf2Dake Gu        vh.mGridView.setScrollEnabled(!freeze);
635709bb7083a089e788d84ffa81f2c4f60a1bc8cf2Dake Gu    }
636709bb7083a089e788d84ffa81f2c4f60a1bc8cf2Dake Gu
637c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu    @Override
6383f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu    public void setEntranceTransitionState(RowPresenter.ViewHolder holder,
6393f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu            boolean afterEntrance) {
6403f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu        super.setEntranceTransitionState(holder, afterEntrance);
641c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu        ((ViewHolder) holder).mGridView.setChildrenVisibility(
6423f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu                afterEntrance? View.VISIBLE : View.INVISIBLE);
643c04ca1b14c5bf9ecac80fc53d3f28a5a7fdd4e77Dake Gu    }
64447520b68e50572a9775a662410c5aff8300c8784Craig Stout}
645