VerticalGridFragment.java revision dfb60d0af5d49da05c584d74245c616263f26b65
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.app;
15739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
16739e3805bf2785e6773aede5e2e1643f537305f9Craig Stoutimport android.support.v17.leanback.R;
17e34cae48707e70442aca13e1b4ab55757292828dDake Guimport android.support.v17.leanback.widget.Row;
18739e3805bf2785e6773aede5e2e1643f537305f9Craig Stoutimport android.support.v17.leanback.widget.VerticalGridPresenter;
19739e3805bf2785e6773aede5e2e1643f537305f9Craig Stoutimport android.support.v17.leanback.widget.ObjectAdapter;
20739e3805bf2785e6773aede5e2e1643f537305f9Craig Stoutimport android.support.v17.leanback.widget.OnItemClickedListener;
21739e3805bf2785e6773aede5e2e1643f537305f9Craig Stoutimport android.support.v17.leanback.widget.OnItemSelectedListener;
22739e3805bf2785e6773aede5e2e1643f537305f9Craig Stoutimport android.support.v17.leanback.widget.SearchOrbView;
23739e3805bf2785e6773aede5e2e1643f537305f9Craig Stoutimport android.app.Fragment;
24739e3805bf2785e6773aede5e2e1643f537305f9Craig Stoutimport android.graphics.drawable.Drawable;
25739e3805bf2785e6773aede5e2e1643f537305f9Craig Stoutimport android.os.Bundle;
2625aacd3f5896ec09053739cc731bdbab3a6f2b81Jerome Poichetimport android.util.Log;
27739e3805bf2785e6773aede5e2e1643f537305f9Craig Stoutimport android.view.LayoutInflater;
28739e3805bf2785e6773aede5e2e1643f537305f9Craig Stoutimport android.view.View;
29739e3805bf2785e6773aede5e2e1643f537305f9Craig Stoutimport android.view.ViewGroup;
30739e3805bf2785e6773aede5e2e1643f537305f9Craig Stoutimport android.widget.ImageView;
31739e3805bf2785e6773aede5e2e1643f537305f9Craig Stoutimport android.widget.TextView;
32739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
33739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout/**
34739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout * Leanback fragment for a vertical grid.
35739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout *
36739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout * Renders a vertical grid of objects given a {@link VerticalGridPresenter} and
37739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout * an {@link ObjectAdapter}.
38739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout */
39739e3805bf2785e6773aede5e2e1643f537305f9Craig Stoutpublic class VerticalGridFragment extends Fragment {
40739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    private static final String TAG = "VerticalGridFragment";
41739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    private static boolean DEBUG = false;
42739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
43dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout    // TODO: remove Params
44739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    private Params mParams;
45dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout
46dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout    private String mTitle;
47dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout    private Drawable mBadgeDrawable;
48739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    private ObjectAdapter mAdapter;
49739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    private VerticalGridPresenter mGridPresenter;
50739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    private VerticalGridPresenter.ViewHolder mGridViewHolder;
51739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    private OnItemSelectedListener mOnItemSelectedListener;
52739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    private OnItemClickedListener mOnItemClickedListener;
53a8d3588c80a232042474aca55a69df78c8ac8cb3Tim Kilbourn    private View.OnClickListener mExternalOnSearchClickedListener;
54739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    private int mSelectedPosition = -1;
55739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
56739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    private ImageView mBadgeView;
57739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    private TextView mTitleView;
58739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    private ViewGroup mBrowseTitle;
59739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    private SearchOrbView mSearchOrbView;
60e34cae48707e70442aca13e1b4ab55757292828dDake Gu    private boolean mShowingTitle = true;
61e34cae48707e70442aca13e1b4ab55757292828dDake Gu
62e34cae48707e70442aca13e1b4ab55757292828dDake Gu    // transition related
63e34cae48707e70442aca13e1b4ab55757292828dDake Gu    private static TransitionHelper sTransitionHelper = TransitionHelper.getInstance();
64e34cae48707e70442aca13e1b4ab55757292828dDake Gu    private Object mTitleTransition;
65e34cae48707e70442aca13e1b4ab55757292828dDake Gu    private Object mSceneWithTitle;
66e34cae48707e70442aca13e1b4ab55757292828dDake Gu    private Object mSceneWithoutTitle;
67739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
68dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout    @Deprecated
69739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    public static class Params {
70739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        private String mTitle;
71739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        private Drawable mBadgeDrawable;
72739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
73739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        /**
74739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout         * Sets the badge image.
75739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout         */
76739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        public void setBadgeImage(Drawable drawable) {
77739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout            mBadgeDrawable = drawable;
78739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        }
79739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
80739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        /**
81739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout         * Returns the badge image.
82739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout         */
83739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        public Drawable getBadgeImage() {
84739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout            return mBadgeDrawable;
85739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        }
86739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
87739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        /**
88739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout         * Sets a title for the browse fragment.
89739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout         */
90739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        public void setTitle(String title) {
91739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout            mTitle = title;
92739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        }
93739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
94739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        /**
95739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout         * Returns the title for the browse fragment.
96739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout         */
97739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        public String getTitle() {
98739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout            return mTitle;
99739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        }
100739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    }
101739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
102739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    /**
103739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     * Set fragment parameters.
104dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout     * @deprecated Use methods on the fragment directly.
105739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     */
106dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout    @Deprecated
107739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    public void setParams(Params params) {
108739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        mParams = params;
109739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        setBadgeDrawable(mParams.mBadgeDrawable);
110739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        setTitle(mParams.mTitle);
111739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    }
112739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
113739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    /**
114739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     * Returns fragment parameters.
115dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout     * @deprecated Use methods on the fragment directly.
116739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     */
117dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout    @Deprecated
118739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    public Params getParams() {
119739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        return mParams;
120739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    }
121739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
122739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    /**
123dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout     * Sets the badge drawable displayed in the title area.
124dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout     */
125dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout    public void setBadgeDrawable(Drawable drawable) {
126dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout        if (drawable != mBadgeDrawable) {
127dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout            mBadgeDrawable = drawable;
128dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout            setBadgeViewImage();
129dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout        }
130dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout    }
131dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout
132dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout    /**
133dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout     * Returns the badge drawable.
134dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout     */
135dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout    public Drawable getBadgeDrawable() {
136dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout        return mBadgeDrawable;
137dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout    }
138dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout
139dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout    /**
140dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout     * Sets a title for the fragment.
141dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout     */
142dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout    public void setTitle(String title) {
143dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout        mTitle = title;
144dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout        if (mTitleView != null) {
145dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout            mTitleView.setText(mTitle);
146dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout        }
147dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout    }
148dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout
149dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout    /**
150dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout     * Returns the title for the fragment.
151dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout     */
152dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout    public String getTitle() {
153dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout        return mTitle;
154dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout    }
155dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout
156dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout    /**
157dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout     * Sets the grid presenter.
158739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     */
159739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    public void setGridPresenter(VerticalGridPresenter gridPresenter) {
160739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        if (gridPresenter == null) {
161739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout            throw new IllegalArgumentException("Grid presenter may not be null");
162739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        }
163739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        mGridPresenter = gridPresenter;
164e34cae48707e70442aca13e1b4ab55757292828dDake Gu        mGridPresenter.setOnItemSelectedListener(mRowSelectedListener);
165739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        if (mOnItemClickedListener != null) {
166739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout            mGridPresenter.setOnItemClickedListener(mOnItemClickedListener);
167739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        }
168739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    }
169739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
170739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    /**
171739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     * Returns the grid presenter.
172739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     */
173739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    public VerticalGridPresenter getGridPresenter() {
174739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        return mGridPresenter;
175739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    }
176739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
177739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    /**
178739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     * Sets the object adapter for the fragment.
179739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     */
180739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    public void setAdapter(ObjectAdapter adapter) {
181739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        mAdapter = adapter;
182739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        updateAdapter();
183739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    }
184739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
185739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    /**
186739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     * Returns the object adapter.
187739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     */
188739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    public ObjectAdapter getAdapter() {
189739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        return mAdapter;
190739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    }
191739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
192e34cae48707e70442aca13e1b4ab55757292828dDake Gu    final private OnItemSelectedListener mRowSelectedListener = new OnItemSelectedListener() {
193e34cae48707e70442aca13e1b4ab55757292828dDake Gu        @Override
194e34cae48707e70442aca13e1b4ab55757292828dDake Gu        public void onItemSelected(Object item, Row row) {
195e34cae48707e70442aca13e1b4ab55757292828dDake Gu            int position = mGridViewHolder.getGridView().getSelectedPosition();
196e34cae48707e70442aca13e1b4ab55757292828dDake Gu            if (DEBUG) Log.v(TAG, "row selected position " + position);
197e34cae48707e70442aca13e1b4ab55757292828dDake Gu            onRowSelected(position);
198e34cae48707e70442aca13e1b4ab55757292828dDake Gu            if (mOnItemSelectedListener != null) {
199e34cae48707e70442aca13e1b4ab55757292828dDake Gu                mOnItemSelectedListener.onItemSelected(item, row);
200e34cae48707e70442aca13e1b4ab55757292828dDake Gu            }
201e34cae48707e70442aca13e1b4ab55757292828dDake Gu        }
202e34cae48707e70442aca13e1b4ab55757292828dDake Gu    };
203e34cae48707e70442aca13e1b4ab55757292828dDake Gu
204739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    /**
205739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     * Sets an item selection listener.
206739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     */
207739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    public void setOnItemSelectedListener(OnItemSelectedListener listener) {
208739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        mOnItemSelectedListener = listener;
209739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    }
210739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
211e34cae48707e70442aca13e1b4ab55757292828dDake Gu    private void onRowSelected(int position) {
212e34cae48707e70442aca13e1b4ab55757292828dDake Gu        if (position != mSelectedPosition) {
213e34cae48707e70442aca13e1b4ab55757292828dDake Gu            if (!mGridViewHolder.getGridView().hasPreviousViewInSameRow(position)) {
214e34cae48707e70442aca13e1b4ab55757292828dDake Gu                // if has no sibling in front of it,  show title
215e34cae48707e70442aca13e1b4ab55757292828dDake Gu                if (!mShowingTitle) {
216e34cae48707e70442aca13e1b4ab55757292828dDake Gu                    sTransitionHelper.runTransition(mSceneWithTitle, mTitleTransition);
217e34cae48707e70442aca13e1b4ab55757292828dDake Gu                    mShowingTitle = true;
218e34cae48707e70442aca13e1b4ab55757292828dDake Gu                }
219e34cae48707e70442aca13e1b4ab55757292828dDake Gu            } else if (mShowingTitle) {
220e34cae48707e70442aca13e1b4ab55757292828dDake Gu                sTransitionHelper.runTransition(mSceneWithoutTitle, mTitleTransition);
221e34cae48707e70442aca13e1b4ab55757292828dDake Gu                mShowingTitle = false;
222e34cae48707e70442aca13e1b4ab55757292828dDake Gu            }
223e34cae48707e70442aca13e1b4ab55757292828dDake Gu            mSelectedPosition = position;
224e34cae48707e70442aca13e1b4ab55757292828dDake Gu        }
225e34cae48707e70442aca13e1b4ab55757292828dDake Gu    }
226739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
227739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    /**
228739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     * Sets an item clicked listener.
229739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     */
230739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    public void setOnItemClickedListener(OnItemClickedListener listener) {
231739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        mOnItemClickedListener = listener;
232739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        if (mGridPresenter != null) {
233739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout            mGridPresenter.setOnItemClickedListener(mOnItemClickedListener);
234739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        }
235739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    }
236739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
237739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    /**
238739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     * Returns the item clicked listener.
239739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     */
240739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    public OnItemClickedListener getOnItemClickedListener() {
241739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        return mOnItemClickedListener;
242739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    }
243739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
244a8d3588c80a232042474aca55a69df78c8ac8cb3Tim Kilbourn    /**
245a8d3588c80a232042474aca55a69df78c8ac8cb3Tim Kilbourn     * Sets a click listener for the search affordance.
246a8d3588c80a232042474aca55a69df78c8ac8cb3Tim Kilbourn     *
247a8d3588c80a232042474aca55a69df78c8ac8cb3Tim Kilbourn     * The presence of a listener will change the visibility of the search affordance in the
248a8d3588c80a232042474aca55a69df78c8ac8cb3Tim Kilbourn     * title area. When set to non-null the title area will contain a call to search action.
249a8d3588c80a232042474aca55a69df78c8ac8cb3Tim Kilbourn     *
250a8d3588c80a232042474aca55a69df78c8ac8cb3Tim Kilbourn     * The listener onClick method will be invoked when the user click on the search action.
251a8d3588c80a232042474aca55a69df78c8ac8cb3Tim Kilbourn     *
252a8d3588c80a232042474aca55a69df78c8ac8cb3Tim Kilbourn     * @param listener The listener.
253a8d3588c80a232042474aca55a69df78c8ac8cb3Tim Kilbourn     */
254a8d3588c80a232042474aca55a69df78c8ac8cb3Tim Kilbourn    public void setOnSearchClickedListener(View.OnClickListener listener) {
255a8d3588c80a232042474aca55a69df78c8ac8cb3Tim Kilbourn        mExternalOnSearchClickedListener = listener;
256a8d3588c80a232042474aca55a69df78c8ac8cb3Tim Kilbourn        if (mSearchOrbView != null) {
257a8d3588c80a232042474aca55a69df78c8ac8cb3Tim Kilbourn            mSearchOrbView.setOnOrbClickedListener(listener);
258a8d3588c80a232042474aca55a69df78c8ac8cb3Tim Kilbourn        }
259a8d3588c80a232042474aca55a69df78c8ac8cb3Tim Kilbourn    }
260a8d3588c80a232042474aca55a69df78c8ac8cb3Tim Kilbourn
261dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout    private void setBadgeViewImage() {
262739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        if (mBadgeView == null) {
263739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout            return;
264739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        }
265dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout        mBadgeView.setImageDrawable(mBadgeDrawable);
266dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout        if (mBadgeDrawable != null) {
267739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout            mBadgeView.setVisibility(View.VISIBLE);
268dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout            mTitleView.setVisibility(View.GONE);
269739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        } else {
270739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout            mBadgeView.setVisibility(View.GONE);
271dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout            mTitleView.setVisibility(View.VISIBLE);
272739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        }
273739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    }
274739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
275739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    @Override
276739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    public View onCreateView(LayoutInflater inflater, ViewGroup container,
277739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout            Bundle savedInstanceState) {
278e34cae48707e70442aca13e1b4ab55757292828dDake Gu        ViewGroup root = (ViewGroup) inflater.inflate(R.layout.lb_vertical_grid_fragment,
279e34cae48707e70442aca13e1b4ab55757292828dDake Gu                container, false);
280739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
281739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        mBrowseTitle = (ViewGroup) root.findViewById(R.id.browse_title_group);
282739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        mBadgeView = (ImageView) mBrowseTitle.findViewById(R.id.browse_badge);
283739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        mTitleView = (TextView) mBrowseTitle.findViewById(R.id.browse_title);
284739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        mSearchOrbView = (SearchOrbView) mBrowseTitle.findViewById(R.id.browse_orb);
285a8d3588c80a232042474aca55a69df78c8ac8cb3Tim Kilbourn        if (mExternalOnSearchClickedListener != null) {
286a8d3588c80a232042474aca55a69df78c8ac8cb3Tim Kilbourn            mSearchOrbView.setOnOrbClickedListener(mExternalOnSearchClickedListener);
287a8d3588c80a232042474aca55a69df78c8ac8cb3Tim Kilbourn        }
288739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
289dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout        setBadgeViewImage();
290dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout        mTitleView.setText(mTitle);
291739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
292e34cae48707e70442aca13e1b4ab55757292828dDake Gu        mSceneWithTitle = sTransitionHelper.createScene(root, new Runnable() {
293e34cae48707e70442aca13e1b4ab55757292828dDake Gu            @Override
294e34cae48707e70442aca13e1b4ab55757292828dDake Gu            public void run() {
295e34cae48707e70442aca13e1b4ab55757292828dDake Gu                mBrowseTitle.setVisibility(View.VISIBLE);
296e34cae48707e70442aca13e1b4ab55757292828dDake Gu            }
297e34cae48707e70442aca13e1b4ab55757292828dDake Gu        });
298e34cae48707e70442aca13e1b4ab55757292828dDake Gu        mSceneWithoutTitle = sTransitionHelper.createScene(root, new Runnable() {
299e34cae48707e70442aca13e1b4ab55757292828dDake Gu            @Override
300e34cae48707e70442aca13e1b4ab55757292828dDake Gu            public void run() {
301e34cae48707e70442aca13e1b4ab55757292828dDake Gu                mBrowseTitle.setVisibility(View.GONE);
302e34cae48707e70442aca13e1b4ab55757292828dDake Gu            }
303e34cae48707e70442aca13e1b4ab55757292828dDake Gu        });
304e34cae48707e70442aca13e1b4ab55757292828dDake Gu        mTitleTransition = sTransitionHelper.createTransitionSet(false);
305e34cae48707e70442aca13e1b4ab55757292828dDake Gu        Object fade = sTransitionHelper.createFadeTransition(
306e34cae48707e70442aca13e1b4ab55757292828dDake Gu                TransitionHelper.FADE_IN | TransitionHelper.FADE_OUT);
307e34cae48707e70442aca13e1b4ab55757292828dDake Gu        Object changeBounds = sTransitionHelper.createChangeBounds(false);
308e34cae48707e70442aca13e1b4ab55757292828dDake Gu        sTransitionHelper.addTransition(mTitleTransition, fade);
309e34cae48707e70442aca13e1b4ab55757292828dDake Gu        sTransitionHelper.addTransition(mTitleTransition, changeBounds);
310e34cae48707e70442aca13e1b4ab55757292828dDake Gu        sTransitionHelper.excludeChildren(mTitleTransition, R.id.browse_grid_dock, true);
311739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        return root;
312739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    }
313739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
314739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    @Override
315739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    public void onViewCreated(View view, Bundle savedInstanceState) {
316739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        ViewGroup gridDock = (ViewGroup) view.findViewById(R.id.browse_grid_dock);
317739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        mGridViewHolder = mGridPresenter.onCreateViewHolder(gridDock);
318739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        gridDock.addView(mGridViewHolder.view);
319739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
320739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        updateAdapter();
321739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    }
322739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
323739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    @Override
324739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    public void onStart() {
325739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        super.onStart();
326739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        mGridViewHolder.getGridView().requestFocus();
327739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    }
328739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
329739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    @Override
330739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    public void onDestroyView() {
331739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        super.onDestroyView();
332739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        mGridViewHolder = null;
333739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    }
334739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
335739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    /**
336739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     * Sets the selected item position.
337739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     */
338739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    public void setSelectedPosition(int position) {
339739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        mSelectedPosition = position;
340739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        if(mGridViewHolder != null && mGridViewHolder.getGridView().getAdapter() != null) {
341739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout            mGridViewHolder.getGridView().setSelectedPositionSmooth(position);
342739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        }
343739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    }
344739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
345739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    private void updateAdapter() {
346739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        if (mGridViewHolder != null) {
347739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout            mGridPresenter.onBindViewHolder(mGridViewHolder, mAdapter);
348739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout            if (mSelectedPosition != -1) {
349739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout                mGridViewHolder.getGridView().setSelectedPosition(mSelectedPosition);
350739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout            }
351739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        }
352739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    }
353739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout}
354