VerticalGridPresenter.java revision 4d14fb53ebf304ad989afbc57baa71cfcafa4e7a
1739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout/*
2739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout * Copyright (C) 2014 The Android Open Source Project
3739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout *
4739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout * in compliance with the License. You may obtain a copy of the License at
6739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout *
7739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout * http://www.apache.org/licenses/LICENSE-2.0
8739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout *
9739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout * Unless required by applicable law or agreed to in writing, software distributed under the License
10739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout * or implied. See the License for the specific language governing permissions and limitations under
12739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout * the License.
13739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout */
14739e3805bf2785e6773aede5e2e1643f537305f9Craig Stoutpackage android.support.v17.leanback.widget;
15739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
16f4acd3cf076435ce836a6d4a9027b73ec3050defCraig Stoutimport android.content.Context;
17739e3805bf2785e6773aede5e2e1643f537305f9Craig Stoutimport android.support.v17.leanback.R;
18f4acd3cf076435ce836a6d4a9027b73ec3050defCraig Stoutimport android.support.v17.leanback.system.Settings;
19739e3805bf2785e6773aede5e2e1643f537305f9Craig Stoutimport android.view.LayoutInflater;
20739e3805bf2785e6773aede5e2e1643f537305f9Craig Stoutimport android.view.View;
21739e3805bf2785e6773aede5e2e1643f537305f9Craig Stoutimport android.view.ViewGroup;
220d734cb6671b314f84cb4911cd37631177d07fbaCraig Stoutimport android.view.ViewGroup.LayoutParams;
23739e3805bf2785e6773aede5e2e1643f537305f9Craig Stoutimport android.util.Log;
24739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
25739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout/**
26a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * A presenter that renders objects in a {@link VerticalGridView}.
27739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout */
28739e3805bf2785e6773aede5e2e1643f537305f9Craig Stoutpublic class VerticalGridPresenter extends Presenter {
29739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    private static final String TAG = "GridPresenter";
30739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    private static final boolean DEBUG = false;
31739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
3271fddded48048acfa744ac352166770c91a1c2b1Dake Gu    class VerticalGridItemBridgeAdapter extends ItemBridgeAdapter {
3371fddded48048acfa744ac352166770c91a1c2b1Dake Gu        @Override
344d14fb53ebf304ad989afbc57baa71cfcafa4e7aDake Gu        protected void onCreate(ItemBridgeAdapter.ViewHolder viewHolder) {
354d14fb53ebf304ad989afbc57baa71cfcafa4e7aDake Gu            if (mShadowOverlayHelper != null) {
364d14fb53ebf304ad989afbc57baa71cfcafa4e7aDake Gu                mShadowOverlayHelper.onViewCreated(viewHolder.itemView);
374d14fb53ebf304ad989afbc57baa71cfcafa4e7aDake Gu            }
384d14fb53ebf304ad989afbc57baa71cfcafa4e7aDake Gu        }
394d14fb53ebf304ad989afbc57baa71cfcafa4e7aDake Gu
404d14fb53ebf304ad989afbc57baa71cfcafa4e7aDake Gu        @Override
4171fddded48048acfa744ac352166770c91a1c2b1Dake Gu        public void onBind(final ItemBridgeAdapter.ViewHolder itemViewHolder) {
4271fddded48048acfa744ac352166770c91a1c2b1Dake Gu            // Only when having an OnItemClickListner, we attach the OnClickListener.
438df88a1ead9ea62456fc3bbda41657ccf61d5721Dake Gu            if (getOnItemViewClickedListener() != null) {
4471fddded48048acfa744ac352166770c91a1c2b1Dake Gu                final View itemView = itemViewHolder.mHolder.view;
4571fddded48048acfa744ac352166770c91a1c2b1Dake Gu                itemView.setOnClickListener(new View.OnClickListener() {
4671fddded48048acfa744ac352166770c91a1c2b1Dake Gu                    @Override
4771fddded48048acfa744ac352166770c91a1c2b1Dake Gu                    public void onClick(View view) {
4871fddded48048acfa744ac352166770c91a1c2b1Dake Gu                        if (getOnItemViewClickedListener() != null) {
4971fddded48048acfa744ac352166770c91a1c2b1Dake Gu                            // Row is always null
5071fddded48048acfa744ac352166770c91a1c2b1Dake Gu                            getOnItemViewClickedListener().onItemClicked(
5171fddded48048acfa744ac352166770c91a1c2b1Dake Gu                                    itemViewHolder.mHolder, itemViewHolder.mItem, null, null);
5271fddded48048acfa744ac352166770c91a1c2b1Dake Gu                        }
5371fddded48048acfa744ac352166770c91a1c2b1Dake Gu                    }
5471fddded48048acfa744ac352166770c91a1c2b1Dake Gu                });
5571fddded48048acfa744ac352166770c91a1c2b1Dake Gu            }
5671fddded48048acfa744ac352166770c91a1c2b1Dake Gu        }
5771fddded48048acfa744ac352166770c91a1c2b1Dake Gu
5871fddded48048acfa744ac352166770c91a1c2b1Dake Gu        @Override
5971fddded48048acfa744ac352166770c91a1c2b1Dake Gu        public void onUnbind(ItemBridgeAdapter.ViewHolder viewHolder) {
608df88a1ead9ea62456fc3bbda41657ccf61d5721Dake Gu            if (getOnItemViewClickedListener() != null) {
6171fddded48048acfa744ac352166770c91a1c2b1Dake Gu                viewHolder.mHolder.view.setOnClickListener(null);
6271fddded48048acfa744ac352166770c91a1c2b1Dake Gu            }
6371fddded48048acfa744ac352166770c91a1c2b1Dake Gu        }
6471fddded48048acfa744ac352166770c91a1c2b1Dake Gu
6571fddded48048acfa744ac352166770c91a1c2b1Dake Gu        @Override
6671fddded48048acfa744ac352166770c91a1c2b1Dake Gu        public void onAttachedToWindow(ItemBridgeAdapter.ViewHolder viewHolder) {
6771fddded48048acfa744ac352166770c91a1c2b1Dake Gu            viewHolder.itemView.setActivated(true);
6871fddded48048acfa744ac352166770c91a1c2b1Dake Gu        }
6971fddded48048acfa744ac352166770c91a1c2b1Dake Gu    }
7071fddded48048acfa744ac352166770c91a1c2b1Dake Gu
71a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout    /**
72a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout     * ViewHolder for the VerticalGridPresenter.
73a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout     */
74739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    public static class ViewHolder extends Presenter.ViewHolder {
7571fddded48048acfa744ac352166770c91a1c2b1Dake Gu        ItemBridgeAdapter mItemBridgeAdapter;
76739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        final VerticalGridView mGridView;
77739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        boolean mInitialized;
78739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
79739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        public ViewHolder(VerticalGridView view) {
80739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout            super(view);
81739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout            mGridView = view;
82739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        }
83739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
84739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        public VerticalGridView getGridView() {
85739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout            return mGridView;
86739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        }
87739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    }
88739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
89739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    private int mNumColumns = -1;
9041ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield    private int mFocusZoomFactor;
9141ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield    private boolean mUseFocusDimmer;
920d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout    private boolean mShadowEnabled = true;
93947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu    private OnItemViewSelectedListener mOnItemViewSelectedListener;
94947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu    private OnItemViewClickedListener mOnItemViewClickedListener;
954f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout    private boolean mRoundedCornersEnabled = true;
964d14fb53ebf304ad989afbc57baa71cfcafa4e7aDake Gu    private ShadowOverlayHelper mShadowOverlayHelper;
97739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
9841ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield    /**
9941ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield     * Constructs a VerticalGridPresenter with defaults.
10041ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield     * Uses {@link FocusHighlight#ZOOM_FACTOR_MEDIUM} for focus zooming and
10141ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield     * enabled dimming on focus.
10241ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield     */
103739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    public VerticalGridPresenter() {
104a37118706af7d79adeb8b3918fb52fad99ece361Dake Gu        this(FocusHighlight.ZOOM_FACTOR_LARGE);
105739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    }
106739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
10741ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield    /**
10841ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield     * Constructs a VerticalGridPresenter with the given parameters.
10941ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield     *
11041ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield     * @param focusZoomFactor Controls the zoom factor used when an item view is focused. One of
11141ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield     *         {@link FocusHighlight#ZOOM_FACTOR_NONE},
11241ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield     *         {@link FocusHighlight#ZOOM_FACTOR_SMALL},
11341ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield     *         {@link FocusHighlight#ZOOM_FACTOR_XSMALL},
11441ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield     *         {@link FocusHighlight#ZOOM_FACTOR_MEDIUM},
11541ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield     *         {@link FocusHighlight#ZOOM_FACTOR_LARGE}
11641ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield     * enabled dimming on focus.
11741ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield     */
11841ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield    public VerticalGridPresenter(int focusZoomFactor) {
11941ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield        this(focusZoomFactor, true);
12041ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield    }
12141ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield
12241ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield    /**
12341ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield     * Constructs a VerticalGridPresenter with the given parameters.
12441ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield     *
12541ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield     * @param focusZoomFactor Controls the zoom factor used when an item view is focused. One of
12641ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield     *         {@link FocusHighlight#ZOOM_FACTOR_NONE},
12741ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield     *         {@link FocusHighlight#ZOOM_FACTOR_SMALL},
12841ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield     *         {@link FocusHighlight#ZOOM_FACTOR_XSMALL},
12941ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield     *         {@link FocusHighlight#ZOOM_FACTOR_MEDIUM},
13041ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield     *         {@link FocusHighlight#ZOOM_FACTOR_LARGE}
13141ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield     * @param useFocusDimmer determines if the FocusHighlighter will use the dimmer
13241ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield     */
13341ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield    public VerticalGridPresenter(int focusZoomFactor, boolean useFocusDimmer) {
13441ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield        mFocusZoomFactor = focusZoomFactor;
13541ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield        mUseFocusDimmer = useFocusDimmer;
136739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    }
137739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
138739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    /**
139739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     * Sets the number of columns in the vertical grid.
140739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     */
141739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    public void setNumberOfColumns(int numColumns) {
142739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        if (numColumns < 0) {
143739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout            throw new IllegalArgumentException("Invalid number of columns");
144739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        }
145739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        if (mNumColumns != numColumns) {
146739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout            mNumColumns = numColumns;
147739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        }
148739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    }
149739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
150739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    /**
151739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     * Returns the number of columns in the vertical grid.
152739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     */
153739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    public int getNumberOfColumns() {
154739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        return mNumColumns;
155739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    }
156739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
1570d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout    /**
1580d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout     * Enable or disable child shadow.
1590d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout     * This is not only for enable/disable default shadow implementation but also subclass must
1600d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout     * respect this flag.
1610d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout     */
1620d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout    public final void setShadowEnabled(boolean enabled) {
1630d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout        mShadowEnabled = enabled;
1640d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout    }
1650d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout
1660d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout    /**
1670d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout     * Returns true if child shadow is enabled.
1680d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout     * This is not only for enable/disable default shadow implementation but also subclass must
1690d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout     * respect this flag.
1700d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout     */
1710d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout    public final boolean getShadowEnabled() {
1720d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout        return mShadowEnabled;
1730d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout    }
1740d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout
1750d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout    /**
1760d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout     * Returns true if opticalBounds is supported (SDK >= 18) so that default shadow
1770d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout     * is applied to each individual child of {@link VerticalGridView}.
1780d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout     * Subclass may return false to disable.
1790d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout     */
1800d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout    public boolean isUsingDefaultShadow() {
1814d14fb53ebf304ad989afbc57baa71cfcafa4e7aDake Gu        return ShadowOverlayHelper.supportsShadow();
1820d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout    }
1830d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout
18474ecd2848a6ceaed6a4dcaed4748b4fb688de020Dake Gu    /**
1854f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout     * Enables or disabled rounded corners on children of this row.
1864f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout     * Supported on Android SDK >= L.
1874f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout     */
1884f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout    public final void enableChildRoundedCorners(boolean enable) {
1894f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout        mRoundedCornersEnabled = enable;
1904f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout    }
1914f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout
1924f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout    /**
1934f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout     * Returns true if rounded corners are enabled for children of this row.
1944f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout     */
1954f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout    public final boolean areChildRoundedCornersEnabled() {
1964f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout        return mRoundedCornersEnabled;
1974f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout    }
1984f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout
1994f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout    /**
20074ecd2848a6ceaed6a4dcaed4748b4fb688de020Dake Gu     * Returns true if SDK >= L, where Z shadow is enabled so that Z order is enabled
20174ecd2848a6ceaed6a4dcaed4748b4fb688de020Dake Gu     * on each child of vertical grid.   If subclass returns false in isUsingDefaultShadow()
20274ecd2848a6ceaed6a4dcaed4748b4fb688de020Dake Gu     * and does not use Z-shadow on SDK >= L, it should override isUsingZOrder() return false.
20374ecd2848a6ceaed6a4dcaed4748b4fb688de020Dake Gu     */
204f4acd3cf076435ce836a6d4a9027b73ec3050defCraig Stout    public boolean isUsingZOrder(Context context) {
2054d14fb53ebf304ad989afbc57baa71cfcafa4e7aDake Gu        return !Settings.getInstance(context).preferStaticShadows();
20674ecd2848a6ceaed6a4dcaed4748b4fb688de020Dake Gu    }
20774ecd2848a6ceaed6a4dcaed4748b4fb688de020Dake Gu
2080d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout    final boolean needsDefaultShadow() {
2090d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout        return isUsingDefaultShadow() && getShadowEnabled();
2100d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout    }
2110d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout
21241ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield    /**
21341ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield     * Returns the zoom factor used for focus highlighting.
21441ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield     */
21541ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield    public final int getFocusZoomFactor() {
21641ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield        return mFocusZoomFactor;
21741ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield    }
21841ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield
21941ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield    /**
22041ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield     * Returns true if the focus dimmer is used for focus highlighting; false otherwise.
22141ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield     */
22241ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield    public final boolean isFocusDimmerUsed() {
22341ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield        return mUseFocusDimmer;
22441ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield    }
22541ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield
22641ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield
227739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    @Override
228739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    public final ViewHolder onCreateViewHolder(ViewGroup parent) {
229739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        ViewHolder vh = createGridViewHolder(parent);
230739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        vh.mInitialized = false;
23171fddded48048acfa744ac352166770c91a1c2b1Dake Gu        vh.mItemBridgeAdapter = new VerticalGridItemBridgeAdapter();
232739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        initializeGridViewHolder(vh);
233739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        if (!vh.mInitialized) {
234739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout            throw new RuntimeException("super.initializeGridViewHolder() must be called");
235739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        }
236739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        return vh;
237739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    }
238739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
239739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    /**
240739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     * Subclass may override this to inflate a different layout.
241739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     */
242739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    protected ViewHolder createGridViewHolder(ViewGroup parent) {
243739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        View root = LayoutInflater.from(parent.getContext()).inflate(
244cb13a318e577e14461eb008071dddf762847de42Dake Gu                R.layout.lb_vertical_grid, parent, false);
245739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        return new ViewHolder((VerticalGridView) root.findViewById(R.id.browse_grid));
246739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    }
247739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
24874ecd2848a6ceaed6a4dcaed4748b4fb688de020Dake Gu    /**
24974ecd2848a6ceaed6a4dcaed4748b4fb688de020Dake Gu     * Called after a {@link VerticalGridPresenter.ViewHolder} is created.
25074ecd2848a6ceaed6a4dcaed4748b4fb688de020Dake Gu     * Subclasses may override this method and start by calling
25174ecd2848a6ceaed6a4dcaed4748b4fb688de020Dake Gu     * super.initializeGridViewHolder(ViewHolder).
25274ecd2848a6ceaed6a4dcaed4748b4fb688de020Dake Gu     *
25374ecd2848a6ceaed6a4dcaed4748b4fb688de020Dake Gu     * @param vh The ViewHolder to initialize for the vertical grid.
25474ecd2848a6ceaed6a4dcaed4748b4fb688de020Dake Gu     */
255739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    protected void initializeGridViewHolder(ViewHolder vh) {
256739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        if (mNumColumns == -1) {
257739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout            throw new IllegalStateException("Number of columns must be set");
258739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        }
259739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        if (DEBUG) Log.v(TAG, "mNumColumns " + mNumColumns);
260739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        vh.getGridView().setNumColumns(mNumColumns);
261739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        vh.mInitialized = true;
262739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
2634d14fb53ebf304ad989afbc57baa71cfcafa4e7aDake Gu        Context context = vh.mGridView.getContext();
2644d14fb53ebf304ad989afbc57baa71cfcafa4e7aDake Gu        if (mShadowOverlayHelper == null) {
2654d14fb53ebf304ad989afbc57baa71cfcafa4e7aDake Gu            mShadowOverlayHelper = new ShadowOverlayHelper(context, mUseFocusDimmer,
2664d14fb53ebf304ad989afbc57baa71cfcafa4e7aDake Gu                    needsDefaultShadow(), areChildRoundedCornersEnabled(), isUsingZOrder(context));
2670d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout        }
2684d14fb53ebf304ad989afbc57baa71cfcafa4e7aDake Gu        vh.mItemBridgeAdapter.setWrapper(mShadowOverlayHelper.getWrapper());
2694d14fb53ebf304ad989afbc57baa71cfcafa4e7aDake Gu        mShadowOverlayHelper.prepareParentForShadow(vh.mGridView);
2704d14fb53ebf304ad989afbc57baa71cfcafa4e7aDake Gu        vh.getGridView().setFocusDrawingOrderEnabled(mShadowOverlayHelper.getShadowType()
2714d14fb53ebf304ad989afbc57baa71cfcafa4e7aDake Gu                == ShadowOverlayHelper.SHADOW_STATIC);
27246e7de54775fc37dc51041629c79249e6dae3242Dake Gu        FocusHighlightHelper.setupBrowseItemFocusHighlight(vh.mItemBridgeAdapter,
27341ad8b4ffe5adbc5c8568d359786a67a4937964dJohn Butterfield                mFocusZoomFactor, mUseFocusDimmer);
274739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
275739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        final ViewHolder gridViewHolder = vh;
276739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        vh.getGridView().setOnChildSelectedListener(new OnChildSelectedListener() {
277739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout            @Override
278739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout            public void onChildSelected(ViewGroup parent, View view, int position, long id) {
279739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout                selectChildView(gridViewHolder, view);
280739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout            }
281739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        });
282739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    }
283739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
284739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    @Override
285739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    public void onBindViewHolder(Presenter.ViewHolder viewHolder, Object item) {
286739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        if (DEBUG) Log.v(TAG, "onBindViewHolder " + item);
287739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        ViewHolder vh = (ViewHolder) viewHolder;
288739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        vh.mItemBridgeAdapter.setAdapter((ObjectAdapter) item);
289739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        vh.getGridView().setAdapter(vh.mItemBridgeAdapter);
290739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    }
291739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
292739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    @Override
293739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    public void onUnbindViewHolder(Presenter.ViewHolder viewHolder) {
294739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        if (DEBUG) Log.v(TAG, "onUnbindViewHolder");
295739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        ViewHolder vh = (ViewHolder) viewHolder;
296739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        vh.mItemBridgeAdapter.setAdapter(null);
297739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        vh.getGridView().setAdapter(null);
298739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    }
299739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
300739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    /**
301739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     * Sets the item selected listener.
302739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     * Since this is a grid the row parameter is always null.
303947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu     */
304947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu    public final void setOnItemViewSelectedListener(OnItemViewSelectedListener listener) {
305947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu        mOnItemViewSelectedListener = listener;
306947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu    }
307947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu
308947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu    /**
309947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu     * Returns the item selected listener.
310947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu     */
311947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu    public final OnItemViewSelectedListener getOnItemViewSelectedListener() {
312947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu        return mOnItemViewSelectedListener;
313947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu    }
314947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu
315947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu    /**
316739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     * Sets the item clicked listener.
317947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu     * OnItemViewClickedListener will override {@link View.OnClickListener} that
318947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu     * item presenter sets during {@link Presenter#onCreateViewHolder(ViewGroup)}.
319947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu     * So in general, developer should choose one of the listeners but not both.
320947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu     */
321947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu    public final void setOnItemViewClickedListener(OnItemViewClickedListener listener) {
322947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu        mOnItemViewClickedListener = listener;
323947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu    }
324947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu
325947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu    /**
326739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     * Returns the item clicked listener.
327947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu     */
328947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu    public final OnItemViewClickedListener getOnItemViewClickedListener() {
329947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu        return mOnItemViewClickedListener;
330947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu    }
331947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu
332739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    private void selectChildView(ViewHolder vh, View view) {
333947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu        if (getOnItemViewSelectedListener() != null) {
334947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu            ItemBridgeAdapter.ViewHolder ibh = (view == null) ? null :
335947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu                    (ItemBridgeAdapter.ViewHolder) vh.getGridView().getChildViewHolder(view);
336947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu            if (ibh == null) {
337947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu                getOnItemViewSelectedListener().onItemSelected(null, null, null, null);
338947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu            } else {
339947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu                getOnItemViewSelectedListener().onItemSelected(ibh.mHolder, ibh.mItem, null, null);
340947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu            }
341947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu        }
342947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu    }
343739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout}
344