VerticalGridPresenter.java revision 8df88a1ead9ea62456fc3bbda41657ccf61d5721
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
3171fddded48048acfa744ac352166770c91a1c2b1Dake Gu    class VerticalGridItemBridgeAdapter extends ItemBridgeAdapter {
3271fddded48048acfa744ac352166770c91a1c2b1Dake Gu        @Override
3371fddded48048acfa744ac352166770c91a1c2b1Dake Gu        public void onBind(final ItemBridgeAdapter.ViewHolder itemViewHolder) {
3471fddded48048acfa744ac352166770c91a1c2b1Dake Gu            // Only when having an OnItemClickListner, we attach the OnClickListener.
358df88a1ead9ea62456fc3bbda41657ccf61d5721Dake Gu            if (getOnItemViewClickedListener() != null) {
3671fddded48048acfa744ac352166770c91a1c2b1Dake Gu                final View itemView = itemViewHolder.mHolder.view;
3771fddded48048acfa744ac352166770c91a1c2b1Dake Gu                itemView.setOnClickListener(new View.OnClickListener() {
3871fddded48048acfa744ac352166770c91a1c2b1Dake Gu                    @Override
3971fddded48048acfa744ac352166770c91a1c2b1Dake Gu                    public void onClick(View view) {
4071fddded48048acfa744ac352166770c91a1c2b1Dake Gu                        if (getOnItemViewClickedListener() != null) {
4171fddded48048acfa744ac352166770c91a1c2b1Dake Gu                            // Row is always null
4271fddded48048acfa744ac352166770c91a1c2b1Dake Gu                            getOnItemViewClickedListener().onItemClicked(
4371fddded48048acfa744ac352166770c91a1c2b1Dake Gu                                    itemViewHolder.mHolder, itemViewHolder.mItem, null, null);
4471fddded48048acfa744ac352166770c91a1c2b1Dake Gu                        }
4571fddded48048acfa744ac352166770c91a1c2b1Dake Gu                    }
4671fddded48048acfa744ac352166770c91a1c2b1Dake Gu                });
4771fddded48048acfa744ac352166770c91a1c2b1Dake Gu            }
4871fddded48048acfa744ac352166770c91a1c2b1Dake Gu        }
4971fddded48048acfa744ac352166770c91a1c2b1Dake Gu
5071fddded48048acfa744ac352166770c91a1c2b1Dake Gu        @Override
5171fddded48048acfa744ac352166770c91a1c2b1Dake Gu        public void onUnbind(ItemBridgeAdapter.ViewHolder viewHolder) {
528df88a1ead9ea62456fc3bbda41657ccf61d5721Dake Gu            if (getOnItemViewClickedListener() != null) {
5371fddded48048acfa744ac352166770c91a1c2b1Dake Gu                viewHolder.mHolder.view.setOnClickListener(null);
5471fddded48048acfa744ac352166770c91a1c2b1Dake Gu            }
5571fddded48048acfa744ac352166770c91a1c2b1Dake Gu        }
5671fddded48048acfa744ac352166770c91a1c2b1Dake Gu
5771fddded48048acfa744ac352166770c91a1c2b1Dake Gu        @Override
5871fddded48048acfa744ac352166770c91a1c2b1Dake Gu        public void onAttachedToWindow(ItemBridgeAdapter.ViewHolder viewHolder) {
5971fddded48048acfa744ac352166770c91a1c2b1Dake Gu            viewHolder.itemView.setActivated(true);
6071fddded48048acfa744ac352166770c91a1c2b1Dake Gu        }
6171fddded48048acfa744ac352166770c91a1c2b1Dake Gu    }
6271fddded48048acfa744ac352166770c91a1c2b1Dake Gu
63739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    public static class ViewHolder extends Presenter.ViewHolder {
6471fddded48048acfa744ac352166770c91a1c2b1Dake Gu        ItemBridgeAdapter mItemBridgeAdapter;
65739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        final VerticalGridView mGridView;
66739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        boolean mInitialized;
67739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
68739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        public ViewHolder(VerticalGridView view) {
69739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout            super(view);
70739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout            mGridView = view;
71739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        }
72739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
73739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        public VerticalGridView getGridView() {
74739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout            return mGridView;
75739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        }
76739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    }
77739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
78739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    private int mNumColumns = -1;
79739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    private int mZoomFactor;
800d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout    private boolean mShadowEnabled = true;
81947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu    private OnItemViewSelectedListener mOnItemViewSelectedListener;
82947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu    private OnItemViewClickedListener mOnItemViewClickedListener;
834f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout    private boolean mRoundedCornersEnabled = true;
84739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
85739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    public VerticalGridPresenter() {
86a37118706af7d79adeb8b3918fb52fad99ece361Dake Gu        this(FocusHighlight.ZOOM_FACTOR_LARGE);
87739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    }
88739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
89739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    public VerticalGridPresenter(int zoomFactor) {
90739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        mZoomFactor = zoomFactor;
91739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    }
92739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
93739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    /**
94739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     * Sets the number of columns in the vertical grid.
95739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     */
96739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    public void setNumberOfColumns(int numColumns) {
97739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        if (numColumns < 0) {
98739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout            throw new IllegalArgumentException("Invalid number of columns");
99739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        }
100739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        if (mNumColumns != numColumns) {
101739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout            mNumColumns = numColumns;
102739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        }
103739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    }
104739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
105739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    /**
106739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     * Returns the number of columns in the vertical grid.
107739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     */
108739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    public int getNumberOfColumns() {
109739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        return mNumColumns;
110739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    }
111739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
1120d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout    /**
1130d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout     * Enable or disable child shadow.
1140d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout     * This is not only for enable/disable default shadow implementation but also subclass must
1150d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout     * respect this flag.
1160d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout     */
1170d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout    public final void setShadowEnabled(boolean enabled) {
1180d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout        mShadowEnabled = enabled;
1190d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout    }
1200d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout
1210d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout    /**
1220d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout     * Returns true if child shadow is enabled.
1230d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout     * This is not only for enable/disable default shadow implementation but also subclass must
1240d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout     * respect this flag.
1250d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout     */
1260d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout    public final boolean getShadowEnabled() {
1270d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout        return mShadowEnabled;
1280d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout    }
1290d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout
1300d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout    /**
1310d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout     * Returns true if opticalBounds is supported (SDK >= 18) so that default shadow
1320d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout     * is applied to each individual child of {@link VerticalGridView}.
1330d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout     * Subclass may return false to disable.
1340d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout     */
1350d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout    public boolean isUsingDefaultShadow() {
1360d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout        return ShadowOverlayContainer.supportsShadow();
1370d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout    }
1380d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout
13974ecd2848a6ceaed6a4dcaed4748b4fb688de020Dake Gu    /**
1404f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout     * Enables or disabled rounded corners on children of this row.
1414f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout     * Supported on Android SDK >= L.
1424f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout     */
1434f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout    public final void enableChildRoundedCorners(boolean enable) {
1444f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout        mRoundedCornersEnabled = enable;
1454f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout    }
1464f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout
1474f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout    /**
1484f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout     * Returns true if rounded corners are enabled for children of this row.
1494f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout     */
1504f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout    public final boolean areChildRoundedCornersEnabled() {
1514f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout        return mRoundedCornersEnabled;
1524f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout    }
1534f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout
1544f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout    /**
15574ecd2848a6ceaed6a4dcaed4748b4fb688de020Dake Gu     * Returns true if SDK >= L, where Z shadow is enabled so that Z order is enabled
15674ecd2848a6ceaed6a4dcaed4748b4fb688de020Dake Gu     * on each child of vertical grid.   If subclass returns false in isUsingDefaultShadow()
15774ecd2848a6ceaed6a4dcaed4748b4fb688de020Dake Gu     * and does not use Z-shadow on SDK >= L, it should override isUsingZOrder() return false.
15874ecd2848a6ceaed6a4dcaed4748b4fb688de020Dake Gu     */
15974ecd2848a6ceaed6a4dcaed4748b4fb688de020Dake Gu    public boolean isUsingZOrder() {
16074ecd2848a6ceaed6a4dcaed4748b4fb688de020Dake Gu        return ShadowHelper.getInstance().usesZShadow();
16174ecd2848a6ceaed6a4dcaed4748b4fb688de020Dake Gu    }
16274ecd2848a6ceaed6a4dcaed4748b4fb688de020Dake Gu
1630d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout    final boolean needsDefaultShadow() {
1640d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout        return isUsingDefaultShadow() && getShadowEnabled();
1650d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout    }
1660d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout
167739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    @Override
168739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    public final ViewHolder onCreateViewHolder(ViewGroup parent) {
169739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        ViewHolder vh = createGridViewHolder(parent);
170739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        vh.mInitialized = false;
17171fddded48048acfa744ac352166770c91a1c2b1Dake Gu        vh.mItemBridgeAdapter = new VerticalGridItemBridgeAdapter();
172739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        initializeGridViewHolder(vh);
173739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        if (!vh.mInitialized) {
174739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout            throw new RuntimeException("super.initializeGridViewHolder() must be called");
175739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        }
176739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        return vh;
177739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    }
178739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
179739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    /**
180739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     * Subclass may override this to inflate a different layout.
181739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     */
182739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    protected ViewHolder createGridViewHolder(ViewGroup parent) {
183739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        View root = LayoutInflater.from(parent.getContext()).inflate(
184cb13a318e577e14461eb008071dddf762847de42Dake Gu                R.layout.lb_vertical_grid, parent, false);
185739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        return new ViewHolder((VerticalGridView) root.findViewById(R.id.browse_grid));
186739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    }
187739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
1880d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout    private ItemBridgeAdapter.Wrapper mWrapper = new ItemBridgeAdapter.Wrapper() {
1890d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout        @Override
1900d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout        public View createWrapper(View root) {
1910d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout            ShadowOverlayContainer wrapper = new ShadowOverlayContainer(root.getContext());
1920d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout            wrapper.setLayoutParams(
1930d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout                    new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
19446e7de54775fc37dc51041629c79249e6dae3242Dake Gu            wrapper.initialize(needsDefaultShadow(), true, areChildRoundedCornersEnabled());
1950d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout            return wrapper;
1960d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout        }
1970d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout        @Override
1980d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout        public void wrap(View wrapper, View wrapped) {
1990d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout            ((ShadowOverlayContainer) wrapper).wrap(wrapped);
2000d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout        }
2010d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout    };
2020d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout
20374ecd2848a6ceaed6a4dcaed4748b4fb688de020Dake Gu    /**
20474ecd2848a6ceaed6a4dcaed4748b4fb688de020Dake Gu     * Called after a {@link VerticalGridPresenter.ViewHolder} is created.
20574ecd2848a6ceaed6a4dcaed4748b4fb688de020Dake Gu     * Subclasses may override this method and start by calling
20674ecd2848a6ceaed6a4dcaed4748b4fb688de020Dake Gu     * super.initializeGridViewHolder(ViewHolder).
20774ecd2848a6ceaed6a4dcaed4748b4fb688de020Dake Gu     *
20874ecd2848a6ceaed6a4dcaed4748b4fb688de020Dake Gu     * @param vh The ViewHolder to initialize for the vertical grid.
20974ecd2848a6ceaed6a4dcaed4748b4fb688de020Dake Gu     */
210739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    protected void initializeGridViewHolder(ViewHolder vh) {
211739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        if (mNumColumns == -1) {
212739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout            throw new IllegalStateException("Number of columns must be set");
213739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        }
214739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        if (DEBUG) Log.v(TAG, "mNumColumns " + mNumColumns);
215739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        vh.getGridView().setNumColumns(mNumColumns);
216739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        vh.mInitialized = true;
217739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
21846e7de54775fc37dc51041629c79249e6dae3242Dake Gu        vh.mItemBridgeAdapter.setWrapper(mWrapper);
2194f34a05cdf73b68c3b2eb8678f740ab15225126aCraig Stout        if (needsDefaultShadow() || areChildRoundedCornersEnabled()) {
2200d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout            ShadowOverlayContainer.prepareParentForShadow(vh.getGridView());
2210d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout            ((ViewGroup) vh.view).setClipChildren(false);
2220d734cb6671b314f84cb4911cd37631177d07fbaCraig Stout        }
22374ecd2848a6ceaed6a4dcaed4748b4fb688de020Dake Gu        vh.getGridView().setFocusDrawingOrderEnabled(!isUsingZOrder());
22446e7de54775fc37dc51041629c79249e6dae3242Dake Gu        FocusHighlightHelper.setupBrowseItemFocusHighlight(vh.mItemBridgeAdapter,
22546e7de54775fc37dc51041629c79249e6dae3242Dake Gu                mZoomFactor, true);
226739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
227739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        final ViewHolder gridViewHolder = vh;
228739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        vh.getGridView().setOnChildSelectedListener(new OnChildSelectedListener() {
229739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout            @Override
230739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout            public void onChildSelected(ViewGroup parent, View view, int position, long id) {
231739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout                selectChildView(gridViewHolder, view);
232739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout            }
233739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        });
234739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    }
235739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
236739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    @Override
237739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    public void onBindViewHolder(Presenter.ViewHolder viewHolder, Object item) {
238739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        if (DEBUG) Log.v(TAG, "onBindViewHolder " + item);
239739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        ViewHolder vh = (ViewHolder) viewHolder;
240739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        vh.mItemBridgeAdapter.setAdapter((ObjectAdapter) item);
241739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        vh.getGridView().setAdapter(vh.mItemBridgeAdapter);
242739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    }
243739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
244739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    @Override
245739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    public void onUnbindViewHolder(Presenter.ViewHolder viewHolder) {
246739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        if (DEBUG) Log.v(TAG, "onUnbindViewHolder");
247739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        ViewHolder vh = (ViewHolder) viewHolder;
248739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        vh.mItemBridgeAdapter.setAdapter(null);
249739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        vh.getGridView().setAdapter(null);
250739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    }
251739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
252739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    /**
253739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     * Sets the item selected listener.
254739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     * Since this is a grid the row parameter is always null.
255947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu     */
256947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu    public final void setOnItemViewSelectedListener(OnItemViewSelectedListener listener) {
257947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu        mOnItemViewSelectedListener = listener;
258947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu    }
259947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu
260947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu    /**
261947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu     * Returns the item selected listener.
262947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu     */
263947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu    public final OnItemViewSelectedListener getOnItemViewSelectedListener() {
264947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu        return mOnItemViewSelectedListener;
265947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu    }
266947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu
267947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu    /**
268739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     * Sets the item clicked listener.
269947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu     * OnItemViewClickedListener will override {@link View.OnClickListener} that
270947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu     * item presenter sets during {@link Presenter#onCreateViewHolder(ViewGroup)}.
271947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu     * So in general, developer should choose one of the listeners but not both.
272947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu     */
273947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu    public final void setOnItemViewClickedListener(OnItemViewClickedListener listener) {
274947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu        mOnItemViewClickedListener = listener;
275947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu    }
276947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu
277947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu    /**
278739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     * Returns the item clicked listener.
279947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu     */
280947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu    public final OnItemViewClickedListener getOnItemViewClickedListener() {
281947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu        return mOnItemViewClickedListener;
282947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu    }
283947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu
284739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    private void selectChildView(ViewHolder vh, View view) {
285947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu        if (getOnItemViewSelectedListener() != null) {
286947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu            ItemBridgeAdapter.ViewHolder ibh = (view == null) ? null :
287947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu                    (ItemBridgeAdapter.ViewHolder) vh.getGridView().getChildViewHolder(view);
288947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu            if (ibh == null) {
289947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu                getOnItemViewSelectedListener().onItemSelected(null, null, null, null);
290947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu            } else {
291947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu                getOnItemViewSelectedListener().onItemSelected(ibh.mHolder, ibh.mItem, null, null);
292947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu            }
293947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu        }
294947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu    }
295739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout}
296