VerticalGridPresenter.java revision 46e7de54775fc37dc51041629c79249e6dae3242
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
16739e3805bf2785e6773aede5e2e1643f537305f9Craig Stoutimport android.support.v17.leanback.R;
17739e3805bf2785e6773aede5e2e1643f537305f9Craig Stoutimport android.view.LayoutInflater;
18739e3805bf2785e6773aede5e2e1643f537305f9Craig Stoutimport android.view.View;
19739e3805bf2785e6773aede5e2e1643f537305f9Craig Stoutimport android.view.ViewGroup;
200d734cb6671b314f84cb4911cd37631177d07fbaCraig Stoutimport android.view.ViewGroup.LayoutParams;
21739e3805bf2785e6773aede5e2e1643f537305f9Craig Stoutimport android.util.Log;
22739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
23739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout/**
24739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout * A presenter that renders objects in a vertical grid.
25739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout *
26739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout */
27739e3805bf2785e6773aede5e2e1643f537305f9Craig Stoutpublic class VerticalGridPresenter extends Presenter {
28739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    private static final String TAG = "GridPresenter";
29739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    private static final boolean DEBUG = false;
30739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
31739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    public static class ViewHolder extends Presenter.ViewHolder {
32739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        final ItemBridgeAdapter mItemBridgeAdapter = new ItemBridgeAdapter();
33739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        final VerticalGridView mGridView;
34739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        boolean mInitialized;
35739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
36739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        public ViewHolder(VerticalGridView view) {
37739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout            super(view);
38739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout            mGridView = view;
39739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        }
40739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
41739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        public VerticalGridView getGridView() {
42739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout            return mGridView;
43739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        }
44739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    }
45739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
46739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    private int mNumColumns = -1;
47739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    private int mZoomFactor;
480d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout    private boolean mShadowEnabled = true;
49739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    private OnItemClickedListener mOnItemClickedListener;
50947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu    private OnItemSelectedListener mOnItemSelectedListener;
51947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu    private OnItemViewSelectedListener mOnItemViewSelectedListener;
52947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu    private OnItemViewClickedListener mOnItemViewClickedListener;
534f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout    private boolean mRoundedCornersEnabled = true;
54739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
55739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    public VerticalGridPresenter() {
56a37118706af7d79adeb8b3918fb52fad99ece361Dake Gu        this(FocusHighlight.ZOOM_FACTOR_LARGE);
57739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    }
58739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
59739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    public VerticalGridPresenter(int zoomFactor) {
60739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        mZoomFactor = zoomFactor;
61739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    }
62739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
63739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    /**
64739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     * Sets the number of columns in the vertical grid.
65739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     */
66739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    public void setNumberOfColumns(int numColumns) {
67739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        if (numColumns < 0) {
68739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout            throw new IllegalArgumentException("Invalid number of columns");
69739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        }
70739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        if (mNumColumns != numColumns) {
71739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout            mNumColumns = numColumns;
72739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        }
73739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    }
74739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
75739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    /**
76739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     * Returns the number of columns in the vertical grid.
77739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     */
78739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    public int getNumberOfColumns() {
79739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        return mNumColumns;
80739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    }
81739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
820d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout    /**
830d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout     * Enable or disable child shadow.
840d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout     * This is not only for enable/disable default shadow implementation but also subclass must
850d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout     * respect this flag.
860d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout     */
870d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout    public final void setShadowEnabled(boolean enabled) {
880d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout        mShadowEnabled = enabled;
890d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout    }
900d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout
910d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout    /**
920d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout     * Returns true if child shadow is enabled.
930d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout     * This is not only for enable/disable default shadow implementation but also subclass must
940d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout     * respect this flag.
950d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout     */
960d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout    public final boolean getShadowEnabled() {
970d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout        return mShadowEnabled;
980d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout    }
990d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout
1000d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout    /**
1010d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout     * Returns true if opticalBounds is supported (SDK >= 18) so that default shadow
1020d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout     * is applied to each individual child of {@link VerticalGridView}.
1030d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout     * Subclass may return false to disable.
1040d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout     */
1050d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout    public boolean isUsingDefaultShadow() {
1060d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout        return ShadowOverlayContainer.supportsShadow();
1070d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout    }
1080d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout
10974ecd2848a6ceaed6a4dcaed4748b4fb688de020Dake Gu    /**
1104f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout     * Enables or disabled rounded corners on children of this row.
1114f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout     * Supported on Android SDK >= L.
1124f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout     */
1134f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout    public final void enableChildRoundedCorners(boolean enable) {
1144f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout        mRoundedCornersEnabled = enable;
1154f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout    }
1164f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout
1174f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout    /**
1184f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout     * Returns true if rounded corners are enabled for children of this row.
1194f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout     */
1204f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout    public final boolean areChildRoundedCornersEnabled() {
1214f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout        return mRoundedCornersEnabled;
1224f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout    }
1234f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout
1244f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout    /**
12574ecd2848a6ceaed6a4dcaed4748b4fb688de020Dake Gu     * Returns true if SDK >= L, where Z shadow is enabled so that Z order is enabled
12674ecd2848a6ceaed6a4dcaed4748b4fb688de020Dake Gu     * on each child of vertical grid.   If subclass returns false in isUsingDefaultShadow()
12774ecd2848a6ceaed6a4dcaed4748b4fb688de020Dake Gu     * and does not use Z-shadow on SDK >= L, it should override isUsingZOrder() return false.
12874ecd2848a6ceaed6a4dcaed4748b4fb688de020Dake Gu     */
12974ecd2848a6ceaed6a4dcaed4748b4fb688de020Dake Gu    public boolean isUsingZOrder() {
13074ecd2848a6ceaed6a4dcaed4748b4fb688de020Dake Gu        return ShadowHelper.getInstance().usesZShadow();
13174ecd2848a6ceaed6a4dcaed4748b4fb688de020Dake Gu    }
13274ecd2848a6ceaed6a4dcaed4748b4fb688de020Dake Gu
1330d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout    final boolean needsDefaultShadow() {
1340d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout        return isUsingDefaultShadow() && getShadowEnabled();
1350d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout    }
1360d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout
137739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    @Override
138739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    public final ViewHolder onCreateViewHolder(ViewGroup parent) {
139739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        ViewHolder vh = createGridViewHolder(parent);
140739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        vh.mInitialized = false;
141739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        initializeGridViewHolder(vh);
142739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        if (!vh.mInitialized) {
143739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout            throw new RuntimeException("super.initializeGridViewHolder() must be called");
144739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        }
145739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        return vh;
146739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    }
147739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
148739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    /**
149739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     * Subclass may override this to inflate a different layout.
150739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     */
151739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    protected ViewHolder createGridViewHolder(ViewGroup parent) {
152739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        View root = LayoutInflater.from(parent.getContext()).inflate(
153cb13a318e577e14461eb008071dddf762847de42Dake Gu                R.layout.lb_vertical_grid, parent, false);
154739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        return new ViewHolder((VerticalGridView) root.findViewById(R.id.browse_grid));
155739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    }
156739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
1570d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout    private ItemBridgeAdapter.Wrapper mWrapper = new ItemBridgeAdapter.Wrapper() {
1580d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout        @Override
1590d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout        public View createWrapper(View root) {
1600d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout            ShadowOverlayContainer wrapper = new ShadowOverlayContainer(root.getContext());
1610d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout            wrapper.setLayoutParams(
1620d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout                    new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
16346e7de54775fc37dc51041629c79249e6dae3242Dake Gu            wrapper.initialize(needsDefaultShadow(), true, areChildRoundedCornersEnabled());
1640d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout            return wrapper;
1650d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout        }
1660d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout        @Override
1670d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout        public void wrap(View wrapper, View wrapped) {
1680d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout            ((ShadowOverlayContainer) wrapper).wrap(wrapped);
1690d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout        }
1700d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout    };
1710d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout
17274ecd2848a6ceaed6a4dcaed4748b4fb688de020Dake Gu    /**
17374ecd2848a6ceaed6a4dcaed4748b4fb688de020Dake Gu     * Called after a {@link VerticalGridPresenter.ViewHolder} is created.
17474ecd2848a6ceaed6a4dcaed4748b4fb688de020Dake Gu     * Subclasses may override this method and start by calling
17574ecd2848a6ceaed6a4dcaed4748b4fb688de020Dake Gu     * super.initializeGridViewHolder(ViewHolder).
17674ecd2848a6ceaed6a4dcaed4748b4fb688de020Dake Gu     *
17774ecd2848a6ceaed6a4dcaed4748b4fb688de020Dake Gu     * @param vh The ViewHolder to initialize for the vertical grid.
17874ecd2848a6ceaed6a4dcaed4748b4fb688de020Dake Gu     */
179739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    protected void initializeGridViewHolder(ViewHolder vh) {
180739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        if (mNumColumns == -1) {
181739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout            throw new IllegalStateException("Number of columns must be set");
182739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        }
183739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        if (DEBUG) Log.v(TAG, "mNumColumns " + mNumColumns);
184739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        vh.getGridView().setNumColumns(mNumColumns);
185739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        vh.mInitialized = true;
186739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
18746e7de54775fc37dc51041629c79249e6dae3242Dake Gu        vh.mItemBridgeAdapter.setWrapper(mWrapper);
1884f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout        if (needsDefaultShadow() || areChildRoundedCornersEnabled()) {
1890d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout            ShadowOverlayContainer.prepareParentForShadow(vh.getGridView());
1900d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout            ((ViewGroup) vh.view).setClipChildren(false);
1910d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout        }
19274ecd2848a6ceaed6a4dcaed4748b4fb688de020Dake Gu        vh.getGridView().setFocusDrawingOrderEnabled(!isUsingZOrder());
19346e7de54775fc37dc51041629c79249e6dae3242Dake Gu        FocusHighlightHelper.setupBrowseItemFocusHighlight(vh.mItemBridgeAdapter,
19446e7de54775fc37dc51041629c79249e6dae3242Dake Gu                mZoomFactor, true);
195739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
196739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        final ViewHolder gridViewHolder = vh;
197739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        vh.getGridView().setOnChildSelectedListener(new OnChildSelectedListener() {
198739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout            @Override
199739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout            public void onChildSelected(ViewGroup parent, View view, int position, long id) {
200739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout                selectChildView(gridViewHolder, view);
201739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout            }
202739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        });
203739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
204739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        vh.mItemBridgeAdapter.setAdapterListener(new ItemBridgeAdapter.AdapterListener() {
205739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout            @Override
20653a46b5723708bbb223084ebf3a4fbf6ea4616aeDake Gu            public void onBind(final ItemBridgeAdapter.ViewHolder itemViewHolder) {
207739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout                // Only when having an OnItemClickListner, we attach the OnClickListener.
208947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu                if (getOnItemClickedListener() != null || getOnItemViewClickedListener() != null) {
20953a46b5723708bbb223084ebf3a4fbf6ea4616aeDake Gu                    final View itemView = itemViewHolder.mHolder.view;
210739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout                    itemView.setOnClickListener(new View.OnClickListener() {
211739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout                        @Override
212739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout                        public void onClick(View view) {
213739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout                            if (getOnItemClickedListener() != null) {
214739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout                                // Row is always null
215947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu                                getOnItemClickedListener().onItemClicked(itemViewHolder.mItem,
216947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu                                        null);
217947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu                            }
218947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu                            if (getOnItemViewClickedListener() != null) {
219947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu                                // Row is always null
220947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu                                getOnItemViewClickedListener().onItemClicked(
221947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu                                        itemViewHolder.mHolder, itemViewHolder.mItem, null, null);
222739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout                            }
223739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout                        }
224739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout                    });
225739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout                }
226739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout            }
227e748917a5661b0de79c7082267799f2530badde6Craig Stout
228e748917a5661b0de79c7082267799f2530badde6Craig Stout            @Override
22953a46b5723708bbb223084ebf3a4fbf6ea4616aeDake Gu            public void onUnbind(ItemBridgeAdapter.ViewHolder viewHolder) {
23053a46b5723708bbb223084ebf3a4fbf6ea4616aeDake Gu                if (getOnItemClickedListener() != null || getOnItemViewClickedListener() != null) {
23153a46b5723708bbb223084ebf3a4fbf6ea4616aeDake Gu                    viewHolder.mHolder.view.setOnClickListener(null);
23253a46b5723708bbb223084ebf3a4fbf6ea4616aeDake Gu                }
23353a46b5723708bbb223084ebf3a4fbf6ea4616aeDake Gu            }
23453a46b5723708bbb223084ebf3a4fbf6ea4616aeDake Gu
23553a46b5723708bbb223084ebf3a4fbf6ea4616aeDake Gu            @Override
236e748917a5661b0de79c7082267799f2530badde6Craig Stout            public void onAttachedToWindow(ItemBridgeAdapter.ViewHolder viewHolder) {
237e748917a5661b0de79c7082267799f2530badde6Craig Stout                viewHolder.itemView.setActivated(true);
238e748917a5661b0de79c7082267799f2530badde6Craig Stout            }
239739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        });
240739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    }
241739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
242739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    @Override
243739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    public void onBindViewHolder(Presenter.ViewHolder viewHolder, Object item) {
244739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        if (DEBUG) Log.v(TAG, "onBindViewHolder " + item);
245739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        ViewHolder vh = (ViewHolder) viewHolder;
246739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        vh.mItemBridgeAdapter.setAdapter((ObjectAdapter) item);
247739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        vh.getGridView().setAdapter(vh.mItemBridgeAdapter);
248739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    }
249739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
250739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    @Override
251739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    public void onUnbindViewHolder(Presenter.ViewHolder viewHolder) {
252739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        if (DEBUG) Log.v(TAG, "onUnbindViewHolder");
253739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        ViewHolder vh = (ViewHolder) viewHolder;
254739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        vh.mItemBridgeAdapter.setAdapter(null);
255739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        vh.getGridView().setAdapter(null);
256739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    }
257739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
258739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    /**
259739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     * Sets the item selected listener.
260739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     * Since this is a grid the row parameter is always null.
261afe1da48b4673f64c67c130237dd485a34a69c1bDake Gu     * @deprecated Use {@link #setOnItemViewSelectedListener(OnItemViewSelectedListener)}
262739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     */
263739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    public final void setOnItemSelectedListener(OnItemSelectedListener listener) {
264739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        mOnItemSelectedListener = listener;
265739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    }
266739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
267739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    /**
268739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     * Returns the item selected listener.
269afe1da48b4673f64c67c130237dd485a34a69c1bDake Gu     * @deprecated Use {@link #getOnItemViewSelectedListener()}
270739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     */
271739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    public final OnItemSelectedListener getOnItemSelectedListener() {
272739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        return mOnItemSelectedListener;
273739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    }
274739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
275739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    /**
276947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu     * Sets the item selected listener.
277947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu     * Since this is a grid the row parameter is always null.
278947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu     */
279947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu    public final void setOnItemViewSelectedListener(OnItemViewSelectedListener listener) {
280947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu        mOnItemViewSelectedListener = listener;
281947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu    }
282947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu
283947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu    /**
284947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu     * Returns the item selected listener.
285947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu     */
286947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu    public final OnItemViewSelectedListener getOnItemViewSelectedListener() {
287947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu        return mOnItemViewSelectedListener;
288947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu    }
289947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu
290947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu    /**
291739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     * Sets the item clicked listener.
292739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     * OnItemClickedListener will override {@link View.OnClickListener} that
293739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     * item presenter sets during {@link Presenter#onCreateViewHolder(ViewGroup)}.
294739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     * So in general, developer should choose one of the listeners but not both.
295afe1da48b4673f64c67c130237dd485a34a69c1bDake Gu     * @deprecated Use {@link #setOnItemViewClickedListener(OnItemViewClickedListener)}
296739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     */
297739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    public final void setOnItemClickedListener(OnItemClickedListener listener) {
298739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        mOnItemClickedListener = listener;
299739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    }
300739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
301739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    /**
302947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu     * Sets the item clicked listener.
303947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu     * OnItemViewClickedListener will override {@link View.OnClickListener} that
304947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu     * item presenter sets during {@link Presenter#onCreateViewHolder(ViewGroup)}.
305947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu     * So in general, developer should choose one of the listeners but not both.
306947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu     */
307947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu    public final void setOnItemViewClickedListener(OnItemViewClickedListener listener) {
308947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu        mOnItemViewClickedListener = listener;
309947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu    }
310947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu
311947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu    /**
312739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     * Returns the item clicked listener.
313afe1da48b4673f64c67c130237dd485a34a69c1bDake Gu     * @deprecated Use {@link #getOnItemViewClickedListener()}
314739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     */
315739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    public final OnItemClickedListener getOnItemClickedListener() {
316739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        return mOnItemClickedListener;
317739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    }
318739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
319947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu    /**
320947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu     * Returns the item clicked listener.
321947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu     */
322947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu    public final OnItemViewClickedListener getOnItemViewClickedListener() {
323947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu        return mOnItemViewClickedListener;
324947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu    }
325947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu
326739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    private void selectChildView(ViewHolder vh, View view) {
327739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        if (getOnItemSelectedListener() != null) {
328739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout            ItemBridgeAdapter.ViewHolder ibh = (view == null) ? null :
329947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu                    (ItemBridgeAdapter.ViewHolder) vh.getGridView().getChildViewHolder(view);
330947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu            if (ibh == null) {
331947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu                getOnItemSelectedListener().onItemSelected(null, null);
332947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu            } else {
333947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu                getOnItemSelectedListener().onItemSelected(ibh.mItem, null);
334947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu            }
335739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        }
336947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu        if (getOnItemViewSelectedListener() != null) {
337947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu            ItemBridgeAdapter.ViewHolder ibh = (view == null) ? null :
338947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu                    (ItemBridgeAdapter.ViewHolder) vh.getGridView().getChildViewHolder(view);
339947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu            if (ibh == null) {
340947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu                getOnItemViewSelectedListener().onItemSelected(null, null, null, null);
341947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu            } else {
342947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu                getOnItemViewSelectedListener().onItemSelected(ibh.mHolder, ibh.mItem, null, null);
343947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu            }
344947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu        }
345947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu    }
346739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout}
347