VerticalGridFragment.java revision 947dbf076cd019e3c26217fbc7aa21e860d68044
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;
17947dbf076cd019e3c26217fbc7aa21e860d68044Dake Guimport android.support.v17.leanback.widget.OnItemViewClickedListener;
18947dbf076cd019e3c26217fbc7aa21e860d68044Dake Guimport android.support.v17.leanback.widget.OnItemViewSelectedListener;
19947dbf076cd019e3c26217fbc7aa21e860d68044Dake Guimport android.support.v17.leanback.widget.Presenter;
20e34cae48707e70442aca13e1b4ab55757292828dDake Guimport android.support.v17.leanback.widget.Row;
21947dbf076cd019e3c26217fbc7aa21e860d68044Dake Guimport android.support.v17.leanback.widget.RowPresenter;
22731066a59e10ddc7bb6c95d0b91b3e0e11e10396Craig Stoutimport android.support.v17.leanback.widget.TitleView;
23739e3805bf2785e6773aede5e2e1643f537305f9Craig Stoutimport android.support.v17.leanback.widget.VerticalGridPresenter;
24739e3805bf2785e6773aede5e2e1643f537305f9Craig Stoutimport android.support.v17.leanback.widget.ObjectAdapter;
25739e3805bf2785e6773aede5e2e1643f537305f9Craig Stoutimport android.support.v17.leanback.widget.OnItemClickedListener;
26739e3805bf2785e6773aede5e2e1643f537305f9Craig Stoutimport android.support.v17.leanback.widget.OnItemSelectedListener;
27739e3805bf2785e6773aede5e2e1643f537305f9Craig Stoutimport android.support.v17.leanback.widget.SearchOrbView;
28739e3805bf2785e6773aede5e2e1643f537305f9Craig Stoutimport android.app.Fragment;
29739e3805bf2785e6773aede5e2e1643f537305f9Craig Stoutimport android.graphics.drawable.Drawable;
30739e3805bf2785e6773aede5e2e1643f537305f9Craig Stoutimport android.os.Bundle;
3125aacd3f5896ec09053739cc731bdbab3a6f2b81Jerome Poichetimport android.util.Log;
32739e3805bf2785e6773aede5e2e1643f537305f9Craig Stoutimport android.view.LayoutInflater;
33739e3805bf2785e6773aede5e2e1643f537305f9Craig Stoutimport android.view.View;
34739e3805bf2785e6773aede5e2e1643f537305f9Craig Stoutimport android.view.ViewGroup;
359020c0aec57b4e8994d66b7cd1a89c225e9bfa11Craig Stoutimport android.view.ViewGroup.MarginLayoutParams;
36739e3805bf2785e6773aede5e2e1643f537305f9Craig Stoutimport android.widget.ImageView;
37739e3805bf2785e6773aede5e2e1643f537305f9Craig Stoutimport android.widget.TextView;
38739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
39739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout/**
404c0f3062b5edd9750351068f46e5270bb220091dTim Kilbourn * A fragment for creating leanback vertical grids.
41739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout *
424c0f3062b5edd9750351068f46e5270bb220091dTim Kilbourn * <p>Renders a vertical grid of objects given a {@link VerticalGridPresenter} and
43739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout * an {@link ObjectAdapter}.
44739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout */
45739e3805bf2785e6773aede5e2e1643f537305f9Craig Stoutpublic class VerticalGridFragment extends Fragment {
46739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    private static final String TAG = "VerticalGridFragment";
47739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    private static boolean DEBUG = false;
48739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
499020c0aec57b4e8994d66b7cd1a89c225e9bfa11Craig Stout    private BrowseFrameLayout mBrowseFrame;
50dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout    private String mTitle;
51dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout    private Drawable mBadgeDrawable;
52739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    private ObjectAdapter mAdapter;
53739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    private VerticalGridPresenter mGridPresenter;
54739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    private VerticalGridPresenter.ViewHolder mGridViewHolder;
55739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    private OnItemSelectedListener mOnItemSelectedListener;
56739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    private OnItemClickedListener mOnItemClickedListener;
57947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu    private OnItemViewSelectedListener mOnItemViewSelectedListener;
58947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu    private OnItemViewClickedListener mOnItemViewClickedListener;
59a8d3588c80a232042474aca55a69df78c8ac8cb3Tim Kilbourn    private View.OnClickListener mExternalOnSearchClickedListener;
60739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    private int mSelectedPosition = -1;
61739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
62731066a59e10ddc7bb6c95d0b91b3e0e11e10396Craig Stout    private TitleView mTitleView;
634fdd3589c982860b831c0fad63c0082cb9079f47Craig Stout    private SearchOrbView.Colors mSearchAffordanceColors;
64731066a59e10ddc7bb6c95d0b91b3e0e11e10396Craig Stout    private boolean mSearchAffordanceColorSet;
65e34cae48707e70442aca13e1b4ab55757292828dDake Gu    private boolean mShowingTitle = true;
66e34cae48707e70442aca13e1b4ab55757292828dDake Gu
67e34cae48707e70442aca13e1b4ab55757292828dDake Gu    // transition related
68e34cae48707e70442aca13e1b4ab55757292828dDake Gu    private static TransitionHelper sTransitionHelper = TransitionHelper.getInstance();
69731066a59e10ddc7bb6c95d0b91b3e0e11e10396Craig Stout    private Object mTitleUpTransition;
70731066a59e10ddc7bb6c95d0b91b3e0e11e10396Craig Stout    private Object mTitleDownTransition;
71e34cae48707e70442aca13e1b4ab55757292828dDake Gu    private Object mSceneWithTitle;
72e34cae48707e70442aca13e1b4ab55757292828dDake Gu    private Object mSceneWithoutTitle;
73739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
74739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    /**
75dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout     * Sets the badge drawable displayed in the title area.
76dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout     */
77dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout    public void setBadgeDrawable(Drawable drawable) {
78dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout        if (drawable != mBadgeDrawable) {
79dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout            mBadgeDrawable = drawable;
80731066a59e10ddc7bb6c95d0b91b3e0e11e10396Craig Stout            if (mTitleView != null) {
81731066a59e10ddc7bb6c95d0b91b3e0e11e10396Craig Stout                mTitleView.setBadgeDrawable(drawable);
82731066a59e10ddc7bb6c95d0b91b3e0e11e10396Craig Stout            }
83dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout        }
84dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout    }
85dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout
86dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout    /**
87dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout     * Returns the badge drawable.
88dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout     */
89dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout    public Drawable getBadgeDrawable() {
90dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout        return mBadgeDrawable;
91dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout    }
92dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout
93dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout    /**
94dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout     * Sets a title for the fragment.
95dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout     */
96dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout    public void setTitle(String title) {
97dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout        mTitle = title;
98dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout        if (mTitleView != null) {
99731066a59e10ddc7bb6c95d0b91b3e0e11e10396Craig Stout            mTitleView.setTitle(mTitle);
100dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout        }
101dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout    }
102dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout
103dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout    /**
104dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout     * Returns the title for the fragment.
105dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout     */
106dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout    public String getTitle() {
107dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout        return mTitle;
108dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout    }
109dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout
110dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout    /**
111dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout     * Sets the grid presenter.
112739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     */
113739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    public void setGridPresenter(VerticalGridPresenter gridPresenter) {
114739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        if (gridPresenter == null) {
115739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout            throw new IllegalArgumentException("Grid presenter may not be null");
116739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        }
117739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        mGridPresenter = gridPresenter;
118947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu        mGridPresenter.setOnItemViewSelectedListener(mRowSelectedListener);
119947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu        if (mOnItemViewClickedListener != null) {
120947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu            mGridPresenter.setOnItemViewClickedListener(mOnItemViewClickedListener);
121947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu        }
122739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        if (mOnItemClickedListener != null) {
123739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout            mGridPresenter.setOnItemClickedListener(mOnItemClickedListener);
124739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        }
125739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    }
126739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
127739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    /**
128739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     * Returns the grid presenter.
129739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     */
130739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    public VerticalGridPresenter getGridPresenter() {
131739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        return mGridPresenter;
132739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    }
133739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
134739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    /**
135739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     * Sets the object adapter for the fragment.
136739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     */
137739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    public void setAdapter(ObjectAdapter adapter) {
138739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        mAdapter = adapter;
139739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        updateAdapter();
140739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    }
141739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
142739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    /**
143739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     * Returns the object adapter.
144739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     */
145739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    public ObjectAdapter getAdapter() {
146739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        return mAdapter;
147739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    }
148739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
149947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu    final private OnItemViewSelectedListener mRowSelectedListener =
150947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu            new OnItemViewSelectedListener() {
151e34cae48707e70442aca13e1b4ab55757292828dDake Gu        @Override
152947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu        public void onItemSelected(Presenter.ViewHolder itemViewHolder, Object item,
153947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu                RowPresenter.ViewHolder rowViewHolder, Row row) {
154e34cae48707e70442aca13e1b4ab55757292828dDake Gu            int position = mGridViewHolder.getGridView().getSelectedPosition();
155e34cae48707e70442aca13e1b4ab55757292828dDake Gu            if (DEBUG) Log.v(TAG, "row selected position " + position);
156e34cae48707e70442aca13e1b4ab55757292828dDake Gu            onRowSelected(position);
157e34cae48707e70442aca13e1b4ab55757292828dDake Gu            if (mOnItemSelectedListener != null) {
158e34cae48707e70442aca13e1b4ab55757292828dDake Gu                mOnItemSelectedListener.onItemSelected(item, row);
159e34cae48707e70442aca13e1b4ab55757292828dDake Gu            }
160947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu            if (mOnItemViewSelectedListener != null) {
161947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu                mOnItemViewSelectedListener.onItemSelected(itemViewHolder, item,
162947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu                        rowViewHolder, row);
163947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu            }
164e34cae48707e70442aca13e1b4ab55757292828dDake Gu        }
165e34cae48707e70442aca13e1b4ab55757292828dDake Gu    };
166e34cae48707e70442aca13e1b4ab55757292828dDake Gu
167739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    /**
168739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     * Sets an item selection listener.
169947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu     * @deprecated
170739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     */
171739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    public void setOnItemSelectedListener(OnItemSelectedListener listener) {
172739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        mOnItemSelectedListener = listener;
173739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    }
174739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
175947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu    /**
176947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu     * Sets an item selection listener.
177947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu     */
178947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu    public void setOnItemViewSelectedListener(OnItemViewSelectedListener listener) {
179947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu        mOnItemViewSelectedListener = listener;
180947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu    }
181947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu
182e34cae48707e70442aca13e1b4ab55757292828dDake Gu    private void onRowSelected(int position) {
183e34cae48707e70442aca13e1b4ab55757292828dDake Gu        if (position != mSelectedPosition) {
184e34cae48707e70442aca13e1b4ab55757292828dDake Gu            if (!mGridViewHolder.getGridView().hasPreviousViewInSameRow(position)) {
185e34cae48707e70442aca13e1b4ab55757292828dDake Gu                // if has no sibling in front of it,  show title
186e34cae48707e70442aca13e1b4ab55757292828dDake Gu                if (!mShowingTitle) {
187731066a59e10ddc7bb6c95d0b91b3e0e11e10396Craig Stout                    sTransitionHelper.runTransition(mSceneWithTitle, mTitleDownTransition);
188e34cae48707e70442aca13e1b4ab55757292828dDake Gu                    mShowingTitle = true;
189e34cae48707e70442aca13e1b4ab55757292828dDake Gu                }
190e34cae48707e70442aca13e1b4ab55757292828dDake Gu            } else if (mShowingTitle) {
191731066a59e10ddc7bb6c95d0b91b3e0e11e10396Craig Stout                sTransitionHelper.runTransition(mSceneWithoutTitle, mTitleUpTransition);
192e34cae48707e70442aca13e1b4ab55757292828dDake Gu                mShowingTitle = false;
193e34cae48707e70442aca13e1b4ab55757292828dDake Gu            }
194e34cae48707e70442aca13e1b4ab55757292828dDake Gu            mSelectedPosition = position;
195e34cae48707e70442aca13e1b4ab55757292828dDake Gu        }
196e34cae48707e70442aca13e1b4ab55757292828dDake Gu    }
197739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
198739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    /**
199739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     * Sets an item clicked listener.
200947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu     * @deprecated
201739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     */
202739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    public void setOnItemClickedListener(OnItemClickedListener listener) {
203739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        mOnItemClickedListener = listener;
204739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        if (mGridPresenter != null) {
205739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout            mGridPresenter.setOnItemClickedListener(mOnItemClickedListener);
206739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        }
207739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    }
208739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
209739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    /**
210739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     * Returns the item clicked listener.
211947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu     * @deprecated
212739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     */
213739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    public OnItemClickedListener getOnItemClickedListener() {
214739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        return mOnItemClickedListener;
215739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    }
216739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
217a8d3588c80a232042474aca55a69df78c8ac8cb3Tim Kilbourn    /**
218947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu     * Sets an item clicked listener.
219947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu     */
220947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu    public void setOnItemViewClickedListener(OnItemViewClickedListener listener) {
221947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu        mOnItemViewClickedListener = listener;
222947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu        if (mGridPresenter != null) {
223947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu            mGridPresenter.setOnItemViewClickedListener(mOnItemViewClickedListener);
224947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu        }
225947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu    }
226947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu
227947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu    /**
228947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu     * Returns the item clicked listener.
229947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu     */
230947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu    public OnItemViewClickedListener getOnItemViewClickedListener() {
231947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu        return mOnItemViewClickedListener;
232947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu    }
233947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu
234947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu    /**
235a8d3588c80a232042474aca55a69df78c8ac8cb3Tim Kilbourn     * Sets a click listener for the search affordance.
236a8d3588c80a232042474aca55a69df78c8ac8cb3Tim Kilbourn     *
2374c0f3062b5edd9750351068f46e5270bb220091dTim Kilbourn     * <p>The presence of a listener will change the visibility of the search
2384c0f3062b5edd9750351068f46e5270bb220091dTim Kilbourn     * affordance in the title area. When set to non-null, the title area will
2394c0f3062b5edd9750351068f46e5270bb220091dTim Kilbourn     * contain a call to search action.
240a8d3588c80a232042474aca55a69df78c8ac8cb3Tim Kilbourn     *
2414c0f3062b5edd9750351068f46e5270bb220091dTim Kilbourn     * <p>The listener's onClick method will be invoked when the user clicks on
2424c0f3062b5edd9750351068f46e5270bb220091dTim Kilbourn     * the search action.
243a8d3588c80a232042474aca55a69df78c8ac8cb3Tim Kilbourn     *
2444c0f3062b5edd9750351068f46e5270bb220091dTim Kilbourn     * @param listener The listener to invoke when the search affordance is
2454c0f3062b5edd9750351068f46e5270bb220091dTim Kilbourn     *        clicked, or null to hide the search affordance.
246a8d3588c80a232042474aca55a69df78c8ac8cb3Tim Kilbourn     */
247a8d3588c80a232042474aca55a69df78c8ac8cb3Tim Kilbourn    public void setOnSearchClickedListener(View.OnClickListener listener) {
248a8d3588c80a232042474aca55a69df78c8ac8cb3Tim Kilbourn        mExternalOnSearchClickedListener = listener;
249731066a59e10ddc7bb6c95d0b91b3e0e11e10396Craig Stout        if (mTitleView != null) {
250731066a59e10ddc7bb6c95d0b91b3e0e11e10396Craig Stout            mTitleView.setOnSearchClickedListener(listener);
251731066a59e10ddc7bb6c95d0b91b3e0e11e10396Craig Stout        }
252731066a59e10ddc7bb6c95d0b91b3e0e11e10396Craig Stout    }
253731066a59e10ddc7bb6c95d0b91b3e0e11e10396Craig Stout
254731066a59e10ddc7bb6c95d0b91b3e0e11e10396Craig Stout    /**
2554fdd3589c982860b831c0fad63c0082cb9079f47Craig Stout     * Sets the {@link SearchOrbView.Colors} used to draw the search affordance.
256731066a59e10ddc7bb6c95d0b91b3e0e11e10396Craig Stout     */
2574fdd3589c982860b831c0fad63c0082cb9079f47Craig Stout    public void setSearchAffordanceColors(SearchOrbView.Colors colors) {
2584fdd3589c982860b831c0fad63c0082cb9079f47Craig Stout        mSearchAffordanceColors = colors;
259731066a59e10ddc7bb6c95d0b91b3e0e11e10396Craig Stout        mSearchAffordanceColorSet = true;
260731066a59e10ddc7bb6c95d0b91b3e0e11e10396Craig Stout        if (mTitleView != null) {
2614fdd3589c982860b831c0fad63c0082cb9079f47Craig Stout            mTitleView.setSearchAffordanceColors(mSearchAffordanceColors);
262a8d3588c80a232042474aca55a69df78c8ac8cb3Tim Kilbourn        }
263a8d3588c80a232042474aca55a69df78c8ac8cb3Tim Kilbourn    }
264a8d3588c80a232042474aca55a69df78c8ac8cb3Tim Kilbourn
265731066a59e10ddc7bb6c95d0b91b3e0e11e10396Craig Stout    /**
2664fdd3589c982860b831c0fad63c0082cb9079f47Craig Stout     * Returns the {@link SearchOrbView.Colors} used to draw the search affordance.
267731066a59e10ddc7bb6c95d0b91b3e0e11e10396Craig Stout     */
2684fdd3589c982860b831c0fad63c0082cb9079f47Craig Stout    public SearchOrbView.Colors getSearchAffordanceColors() {
269731066a59e10ddc7bb6c95d0b91b3e0e11e10396Craig Stout        if (mSearchAffordanceColorSet) {
2704fdd3589c982860b831c0fad63c0082cb9079f47Craig Stout            return mSearchAffordanceColors;
271739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        }
272731066a59e10ddc7bb6c95d0b91b3e0e11e10396Craig Stout        if (mTitleView == null) {
273731066a59e10ddc7bb6c95d0b91b3e0e11e10396Craig Stout            throw new IllegalStateException("Fragment views not yet created");
274739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        }
2754fdd3589c982860b831c0fad63c0082cb9079f47Craig Stout        return mTitleView.getSearchAffordanceColors();
2764fdd3589c982860b831c0fad63c0082cb9079f47Craig Stout    }
2774fdd3589c982860b831c0fad63c0082cb9079f47Craig Stout
2784fdd3589c982860b831c0fad63c0082cb9079f47Craig Stout    /**
2794fdd3589c982860b831c0fad63c0082cb9079f47Craig Stout     * Sets the color used to draw the search affordance.
2804fdd3589c982860b831c0fad63c0082cb9079f47Craig Stout     * A default brighter color will be set by the framework.
2814fdd3589c982860b831c0fad63c0082cb9079f47Craig Stout     *
2824fdd3589c982860b831c0fad63c0082cb9079f47Craig Stout     * @param color The color to use for the search affordance.
2834fdd3589c982860b831c0fad63c0082cb9079f47Craig Stout     */
2844fdd3589c982860b831c0fad63c0082cb9079f47Craig Stout    public void setSearchAffordanceColor(int color) {
2854fdd3589c982860b831c0fad63c0082cb9079f47Craig Stout        setSearchAffordanceColors(new SearchOrbView.Colors(color));
286739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    }
287739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
2884fdd3589c982860b831c0fad63c0082cb9079f47Craig Stout    /**
2894fdd3589c982860b831c0fad63c0082cb9079f47Craig Stout     * Returns the color used to draw the search affordance.
2904fdd3589c982860b831c0fad63c0082cb9079f47Craig Stout     */
2914fdd3589c982860b831c0fad63c0082cb9079f47Craig Stout    public int getSearchAffordanceColor() {
2924fdd3589c982860b831c0fad63c0082cb9079f47Craig Stout        return getSearchAffordanceColors().color;
2934fdd3589c982860b831c0fad63c0082cb9079f47Craig Stout    }
294731066a59e10ddc7bb6c95d0b91b3e0e11e10396Craig Stout
2959020c0aec57b4e8994d66b7cd1a89c225e9bfa11Craig Stout    private final BrowseFrameLayout.OnFocusSearchListener mOnFocusSearchListener =
2969020c0aec57b4e8994d66b7cd1a89c225e9bfa11Craig Stout            new BrowseFrameLayout.OnFocusSearchListener() {
2979020c0aec57b4e8994d66b7cd1a89c225e9bfa11Craig Stout        @Override
2989020c0aec57b4e8994d66b7cd1a89c225e9bfa11Craig Stout        public View onFocusSearch(View focused, int direction) {
2999020c0aec57b4e8994d66b7cd1a89c225e9bfa11Craig Stout            if (DEBUG) Log.v(TAG, "onFocusSearch focused " + focused + " + direction " + direction);
3009020c0aec57b4e8994d66b7cd1a89c225e9bfa11Craig Stout
301731066a59e10ddc7bb6c95d0b91b3e0e11e10396Craig Stout            final View searchOrbView = mTitleView.getSearchAffordanceView();
302731066a59e10ddc7bb6c95d0b91b3e0e11e10396Craig Stout            if (focused == searchOrbView && (
3039020c0aec57b4e8994d66b7cd1a89c225e9bfa11Craig Stout                    direction == View.FOCUS_DOWN || direction == View.FOCUS_RIGHT)) {
3049020c0aec57b4e8994d66b7cd1a89c225e9bfa11Craig Stout                return mGridViewHolder.view;
3059020c0aec57b4e8994d66b7cd1a89c225e9bfa11Craig Stout
306731066a59e10ddc7bb6c95d0b91b3e0e11e10396Craig Stout            } else if (focused != searchOrbView && searchOrbView.getVisibility() == View.VISIBLE
3079020c0aec57b4e8994d66b7cd1a89c225e9bfa11Craig Stout                    && direction == View.FOCUS_UP) {
308731066a59e10ddc7bb6c95d0b91b3e0e11e10396Craig Stout                return searchOrbView;
3099020c0aec57b4e8994d66b7cd1a89c225e9bfa11Craig Stout
3109020c0aec57b4e8994d66b7cd1a89c225e9bfa11Craig Stout            } else {
3119020c0aec57b4e8994d66b7cd1a89c225e9bfa11Craig Stout                return null;
3129020c0aec57b4e8994d66b7cd1a89c225e9bfa11Craig Stout            }
3139020c0aec57b4e8994d66b7cd1a89c225e9bfa11Craig Stout        }
3149020c0aec57b4e8994d66b7cd1a89c225e9bfa11Craig Stout    };
3159020c0aec57b4e8994d66b7cd1a89c225e9bfa11Craig Stout
316739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    @Override
317739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    public View onCreateView(LayoutInflater inflater, ViewGroup container,
318739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout            Bundle savedInstanceState) {
319e34cae48707e70442aca13e1b4ab55757292828dDake Gu        ViewGroup root = (ViewGroup) inflater.inflate(R.layout.lb_vertical_grid_fragment,
320e34cae48707e70442aca13e1b4ab55757292828dDake Gu                container, false);
321739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
3229020c0aec57b4e8994d66b7cd1a89c225e9bfa11Craig Stout        mBrowseFrame = (BrowseFrameLayout) root.findViewById(R.id.browse_frame);
3239020c0aec57b4e8994d66b7cd1a89c225e9bfa11Craig Stout        mBrowseFrame.setOnFocusSearchListener(mOnFocusSearchListener);
3249020c0aec57b4e8994d66b7cd1a89c225e9bfa11Craig Stout
325731066a59e10ddc7bb6c95d0b91b3e0e11e10396Craig Stout        mTitleView = (TitleView) root.findViewById(R.id.browse_title_group);
326731066a59e10ddc7bb6c95d0b91b3e0e11e10396Craig Stout        mTitleView.setBadgeDrawable(mBadgeDrawable);
327731066a59e10ddc7bb6c95d0b91b3e0e11e10396Craig Stout        mTitleView.setTitle(mTitle);
328731066a59e10ddc7bb6c95d0b91b3e0e11e10396Craig Stout        if (mSearchAffordanceColorSet) {
3294fdd3589c982860b831c0fad63c0082cb9079f47Craig Stout            mTitleView.setSearchAffordanceColors(mSearchAffordanceColors);
330731066a59e10ddc7bb6c95d0b91b3e0e11e10396Craig Stout        }
331a8d3588c80a232042474aca55a69df78c8ac8cb3Tim Kilbourn        if (mExternalOnSearchClickedListener != null) {
332731066a59e10ddc7bb6c95d0b91b3e0e11e10396Craig Stout            mTitleView.setOnSearchClickedListener(mExternalOnSearchClickedListener);
333a8d3588c80a232042474aca55a69df78c8ac8cb3Tim Kilbourn        }
334739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
335e34cae48707e70442aca13e1b4ab55757292828dDake Gu        mSceneWithTitle = sTransitionHelper.createScene(root, new Runnable() {
336e34cae48707e70442aca13e1b4ab55757292828dDake Gu            @Override
337e34cae48707e70442aca13e1b4ab55757292828dDake Gu            public void run() {
338731066a59e10ddc7bb6c95d0b91b3e0e11e10396Craig Stout                TitleTransitionHelper.showTitle(mTitleView, true);
339e34cae48707e70442aca13e1b4ab55757292828dDake Gu            }
340e34cae48707e70442aca13e1b4ab55757292828dDake Gu        });
341e34cae48707e70442aca13e1b4ab55757292828dDake Gu        mSceneWithoutTitle = sTransitionHelper.createScene(root, new Runnable() {
342e34cae48707e70442aca13e1b4ab55757292828dDake Gu            @Override
343e34cae48707e70442aca13e1b4ab55757292828dDake Gu            public void run() {
344731066a59e10ddc7bb6c95d0b91b3e0e11e10396Craig Stout                TitleTransitionHelper.showTitle(mTitleView, false);
345e34cae48707e70442aca13e1b4ab55757292828dDake Gu            }
346e34cae48707e70442aca13e1b4ab55757292828dDake Gu        });
347731066a59e10ddc7bb6c95d0b91b3e0e11e10396Craig Stout        mTitleUpTransition = TitleTransitionHelper.createTransitionTitleUp(sTransitionHelper);
348731066a59e10ddc7bb6c95d0b91b3e0e11e10396Craig Stout        mTitleDownTransition = TitleTransitionHelper.createTransitionTitleDown(sTransitionHelper);
349731066a59e10ddc7bb6c95d0b91b3e0e11e10396Craig Stout        sTransitionHelper.excludeChildren(mTitleUpTransition, R.id.browse_grid_dock, true);
350731066a59e10ddc7bb6c95d0b91b3e0e11e10396Craig Stout        sTransitionHelper.excludeChildren(mTitleDownTransition, R.id.browse_grid_dock, true);
351739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
352731066a59e10ddc7bb6c95d0b91b3e0e11e10396Craig Stout        return root;
3539020c0aec57b4e8994d66b7cd1a89c225e9bfa11Craig Stout    }
3549020c0aec57b4e8994d66b7cd1a89c225e9bfa11Craig Stout
355739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    @Override
356739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    public void onViewCreated(View view, Bundle savedInstanceState) {
357739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        ViewGroup gridDock = (ViewGroup) view.findViewById(R.id.browse_grid_dock);
358739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        mGridViewHolder = mGridPresenter.onCreateViewHolder(gridDock);
359739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        gridDock.addView(mGridViewHolder.view);
360739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
361739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        updateAdapter();
362739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    }
363739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
364739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    @Override
365739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    public void onStart() {
366739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        super.onStart();
367739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        mGridViewHolder.getGridView().requestFocus();
368739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    }
369739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
370739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    @Override
371739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    public void onDestroyView() {
372739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        super.onDestroyView();
373739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        mGridViewHolder = null;
374739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    }
375739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
376739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    /**
377739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     * Sets the selected item position.
378739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout     */
379739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    public void setSelectedPosition(int position) {
380739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        mSelectedPosition = position;
381739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        if(mGridViewHolder != null && mGridViewHolder.getGridView().getAdapter() != null) {
382739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout            mGridViewHolder.getGridView().setSelectedPositionSmooth(position);
383739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        }
384739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    }
385739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
386739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    private void updateAdapter() {
387739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        if (mGridViewHolder != null) {
388739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout            mGridPresenter.onBindViewHolder(mGridViewHolder, mAdapter);
389739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout            if (mSelectedPosition != -1) {
390739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout                mGridViewHolder.getGridView().setSelectedPosition(mSelectedPosition);
391739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout            }
392739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout        }
393739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout    }
394739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout}
395