VerticalGridSupportFragment.java revision 6193c12a1897723c87b41f4e304a8cd04deef2dc
1/* This file is auto-generated from VerticalGridFragment.java.  DO NOT MODIFY. */
2
3/*
4 * Copyright (C) 2014 The Android Open Source Project
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
7 * in compliance with the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software distributed under the License
12 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
13 * or implied. See the License for the specific language governing permissions and limitations under
14 * the License.
15 */
16package android.support.v17.leanback.app;
17
18import android.support.v17.leanback.R;
19import android.support.v17.leanback.transition.TransitionHelper;
20import android.support.v17.leanback.widget.BrowseFrameLayout;
21import android.support.v17.leanback.widget.OnItemViewClickedListener;
22import android.support.v17.leanback.widget.OnItemViewSelectedListener;
23import android.support.v17.leanback.widget.Presenter;
24import android.support.v17.leanback.widget.Row;
25import android.support.v17.leanback.widget.RowPresenter;
26import android.support.v17.leanback.widget.TitleView;
27import android.support.v17.leanback.widget.VerticalGridPresenter;
28import android.support.v17.leanback.widget.ObjectAdapter;
29import android.support.v17.leanback.widget.OnItemClickedListener;
30import android.support.v17.leanback.widget.OnItemSelectedListener;
31import android.support.v17.leanback.widget.SearchOrbView;
32import android.support.v4.app.Fragment;
33import android.graphics.drawable.Drawable;
34import android.os.Bundle;
35import android.util.Log;
36import android.view.LayoutInflater;
37import android.view.View;
38import android.view.ViewGroup;
39import android.view.ViewGroup.MarginLayoutParams;
40import android.widget.ImageView;
41import android.widget.TextView;
42
43/**
44 * A fragment for creating leanback vertical grids.
45 *
46 * <p>Renders a vertical grid of objects given a {@link VerticalGridPresenter} and
47 * an {@link ObjectAdapter}.
48 */
49public class VerticalGridSupportFragment extends Fragment {
50    private static final String TAG = "VerticalGridSupportFragment";
51    private static boolean DEBUG = false;
52
53    private BrowseFrameLayout mBrowseFrame;
54    private String mTitle;
55    private Drawable mBadgeDrawable;
56    private ObjectAdapter mAdapter;
57    private VerticalGridPresenter mGridPresenter;
58    private VerticalGridPresenter.ViewHolder mGridViewHolder;
59    private OnItemSelectedListener mOnItemSelectedListener;
60    private OnItemClickedListener mOnItemClickedListener;
61    private OnItemViewSelectedListener mOnItemViewSelectedListener;
62    private OnItemViewClickedListener mOnItemViewClickedListener;
63    private View.OnClickListener mExternalOnSearchClickedListener;
64    private int mSelectedPosition = -1;
65
66    private TitleView mTitleView;
67    private SearchOrbView.Colors mSearchAffordanceColors;
68    private boolean mSearchAffordanceColorSet;
69    private boolean mShowingTitle = true;
70
71    // transition related
72    private static TransitionHelper sTransitionHelper = TransitionHelper.getInstance();
73    private Object mTitleUpTransition;
74    private Object mTitleDownTransition;
75    private Object mSceneWithTitle;
76    private Object mSceneWithoutTitle;
77
78    /**
79     * Sets the badge drawable displayed in the title area.
80     */
81    public void setBadgeDrawable(Drawable drawable) {
82        if (drawable != mBadgeDrawable) {
83            mBadgeDrawable = drawable;
84            if (mTitleView != null) {
85                mTitleView.setBadgeDrawable(drawable);
86            }
87        }
88    }
89
90    /**
91     * Returns the badge drawable.
92     */
93    public Drawable getBadgeDrawable() {
94        return mBadgeDrawable;
95    }
96
97    /**
98     * Sets a title for the fragment.
99     */
100    public void setTitle(String title) {
101        mTitle = title;
102        if (mTitleView != null) {
103            mTitleView.setTitle(mTitle);
104        }
105    }
106
107    /**
108     * Returns the title for the fragment.
109     */
110    public String getTitle() {
111        return mTitle;
112    }
113
114    /**
115     * Sets the grid presenter.
116     */
117    public void setGridPresenter(VerticalGridPresenter gridPresenter) {
118        if (gridPresenter == null) {
119            throw new IllegalArgumentException("Grid presenter may not be null");
120        }
121        mGridPresenter = gridPresenter;
122        mGridPresenter.setOnItemViewSelectedListener(mRowSelectedListener);
123        if (mOnItemViewClickedListener != null) {
124            mGridPresenter.setOnItemViewClickedListener(mOnItemViewClickedListener);
125        }
126        if (mOnItemClickedListener != null) {
127            mGridPresenter.setOnItemClickedListener(mOnItemClickedListener);
128        }
129    }
130
131    /**
132     * Returns the grid presenter.
133     */
134    public VerticalGridPresenter getGridPresenter() {
135        return mGridPresenter;
136    }
137
138    /**
139     * Sets the object adapter for the fragment.
140     */
141    public void setAdapter(ObjectAdapter adapter) {
142        mAdapter = adapter;
143        updateAdapter();
144    }
145
146    /**
147     * Returns the object adapter.
148     */
149    public ObjectAdapter getAdapter() {
150        return mAdapter;
151    }
152
153    final private OnItemViewSelectedListener mRowSelectedListener =
154            new OnItemViewSelectedListener() {
155        @Override
156        public void onItemSelected(Presenter.ViewHolder itemViewHolder, Object item,
157                RowPresenter.ViewHolder rowViewHolder, Row row) {
158            int position = mGridViewHolder.getGridView().getSelectedPosition();
159            if (DEBUG) Log.v(TAG, "row selected position " + position);
160            onRowSelected(position);
161            if (mOnItemSelectedListener != null) {
162                mOnItemSelectedListener.onItemSelected(item, row);
163            }
164            if (mOnItemViewSelectedListener != null) {
165                mOnItemViewSelectedListener.onItemSelected(itemViewHolder, item,
166                        rowViewHolder, row);
167            }
168        }
169    };
170
171    /**
172     * Sets an item selection listener.
173     * @deprecated Use {@link #setOnItemViewSelectedListener(OnItemViewSelectedListener)}
174     */
175    public void setOnItemSelectedListener(OnItemSelectedListener listener) {
176        mOnItemSelectedListener = listener;
177    }
178
179    /**
180     * Sets an item selection listener.
181     */
182    public void setOnItemViewSelectedListener(OnItemViewSelectedListener listener) {
183        mOnItemViewSelectedListener = listener;
184    }
185
186    private void onRowSelected(int position) {
187        if (position != mSelectedPosition) {
188            if (!mGridViewHolder.getGridView().hasPreviousViewInSameRow(position)) {
189                // if has no sibling in front of it,  show title
190                if (!mShowingTitle) {
191                    sTransitionHelper.runTransition(mSceneWithTitle, mTitleDownTransition);
192                    mShowingTitle = true;
193                }
194            } else if (mShowingTitle) {
195                sTransitionHelper.runTransition(mSceneWithoutTitle, mTitleUpTransition);
196                mShowingTitle = false;
197            }
198            mSelectedPosition = position;
199        }
200    }
201
202    /**
203     * Sets an item clicked listener.
204     * @deprecated Use {@link #setOnItemViewClickedListener(OnItemViewClickedListener)}
205     */
206    public void setOnItemClickedListener(OnItemClickedListener listener) {
207        mOnItemClickedListener = listener;
208        if (mGridPresenter != null) {
209            mGridPresenter.setOnItemClickedListener(mOnItemClickedListener);
210        }
211    }
212
213    /**
214     * Returns the item clicked listener.
215     * @deprecated Use {@link #getOnItemViewClickedListener()}
216     */
217    public OnItemClickedListener getOnItemClickedListener() {
218        return mOnItemClickedListener;
219    }
220
221    /**
222     * Sets an item clicked listener.
223     */
224    public void setOnItemViewClickedListener(OnItemViewClickedListener listener) {
225        mOnItemViewClickedListener = listener;
226        if (mGridPresenter != null) {
227            mGridPresenter.setOnItemViewClickedListener(mOnItemViewClickedListener);
228        }
229    }
230
231    /**
232     * Returns the item clicked listener.
233     */
234    public OnItemViewClickedListener getOnItemViewClickedListener() {
235        return mOnItemViewClickedListener;
236    }
237
238    /**
239     * Sets a click listener for the search affordance.
240     *
241     * <p>The presence of a listener will change the visibility of the search
242     * affordance in the title area. When set to non-null, the title area will
243     * contain a call to search action.
244     *
245     * <p>The listener's onClick method will be invoked when the user clicks on
246     * the search action.
247     *
248     * @param listener The listener to invoke when the search affordance is
249     *        clicked, or null to hide the search affordance.
250     */
251    public void setOnSearchClickedListener(View.OnClickListener listener) {
252        mExternalOnSearchClickedListener = listener;
253        if (mTitleView != null) {
254            mTitleView.setOnSearchClickedListener(listener);
255        }
256    }
257
258    /**
259     * Sets the {@link SearchOrbView.Colors} used to draw the search affordance.
260     */
261    public void setSearchAffordanceColors(SearchOrbView.Colors colors) {
262        mSearchAffordanceColors = colors;
263        mSearchAffordanceColorSet = true;
264        if (mTitleView != null) {
265            mTitleView.setSearchAffordanceColors(mSearchAffordanceColors);
266        }
267    }
268
269    /**
270     * Returns the {@link SearchOrbView.Colors} used to draw the search affordance.
271     */
272    public SearchOrbView.Colors getSearchAffordanceColors() {
273        if (mSearchAffordanceColorSet) {
274            return mSearchAffordanceColors;
275        }
276        if (mTitleView == null) {
277            throw new IllegalStateException("Fragment views not yet created");
278        }
279        return mTitleView.getSearchAffordanceColors();
280    }
281
282    /**
283     * Sets the color used to draw the search affordance.
284     * A default brighter color will be set by the framework.
285     *
286     * @param color The color to use for the search affordance.
287     */
288    public void setSearchAffordanceColor(int color) {
289        setSearchAffordanceColors(new SearchOrbView.Colors(color));
290    }
291
292    /**
293     * Returns the color used to draw the search affordance.
294     */
295    public int getSearchAffordanceColor() {
296        return getSearchAffordanceColors().color;
297    }
298
299    private final BrowseFrameLayout.OnFocusSearchListener mOnFocusSearchListener =
300            new BrowseFrameLayout.OnFocusSearchListener() {
301        @Override
302        public View onFocusSearch(View focused, int direction) {
303            if (DEBUG) Log.v(TAG, "onFocusSearch focused " + focused + " + direction " + direction);
304
305            final View searchOrbView = mTitleView.getSearchAffordanceView();
306            if (focused == searchOrbView && (
307                    direction == View.FOCUS_DOWN || direction == View.FOCUS_RIGHT)) {
308                return mGridViewHolder.view;
309
310            } else if (focused != searchOrbView && searchOrbView.getVisibility() == View.VISIBLE
311                    && direction == View.FOCUS_UP) {
312                return searchOrbView;
313
314            } else {
315                return null;
316            }
317        }
318    };
319
320    @Override
321    public View onCreateView(LayoutInflater inflater, ViewGroup container,
322            Bundle savedInstanceState) {
323        ViewGroup root = (ViewGroup) inflater.inflate(R.layout.lb_vertical_grid_fragment,
324                container, false);
325
326        mBrowseFrame = (BrowseFrameLayout) root.findViewById(R.id.browse_frame);
327        mBrowseFrame.setOnFocusSearchListener(mOnFocusSearchListener);
328
329        mTitleView = (TitleView) root.findViewById(R.id.browse_title_group);
330        mTitleView.setBadgeDrawable(mBadgeDrawable);
331        mTitleView.setTitle(mTitle);
332        if (mSearchAffordanceColorSet) {
333            mTitleView.setSearchAffordanceColors(mSearchAffordanceColors);
334        }
335        if (mExternalOnSearchClickedListener != null) {
336            mTitleView.setOnSearchClickedListener(mExternalOnSearchClickedListener);
337        }
338
339        mSceneWithTitle = sTransitionHelper.createScene(root, new Runnable() {
340            @Override
341            public void run() {
342                mTitleView.setVisibility(View.VISIBLE);
343            }
344        });
345        mSceneWithoutTitle = sTransitionHelper.createScene(root, new Runnable() {
346            @Override
347            public void run() {
348                mTitleView.setVisibility(View.INVISIBLE);
349            }
350        });
351        mTitleUpTransition = TitleTransitionHelper.createTransitionTitleUp(sTransitionHelper);
352        mTitleDownTransition = TitleTransitionHelper.createTransitionTitleDown(sTransitionHelper);
353        sTransitionHelper.excludeChildren(mTitleUpTransition, R.id.browse_grid_dock, true);
354        sTransitionHelper.excludeChildren(mTitleDownTransition, R.id.browse_grid_dock, true);
355
356        return root;
357    }
358
359    @Override
360    public void onViewCreated(View view, Bundle savedInstanceState) {
361        ViewGroup gridDock = (ViewGroup) view.findViewById(R.id.browse_grid_dock);
362        mGridViewHolder = mGridPresenter.onCreateViewHolder(gridDock);
363        gridDock.addView(mGridViewHolder.view);
364
365        updateAdapter();
366    }
367
368    @Override
369    public void onStart() {
370        super.onStart();
371        mGridViewHolder.getGridView().requestFocus();
372    }
373
374    @Override
375    public void onDestroyView() {
376        super.onDestroyView();
377        mGridViewHolder = null;
378    }
379
380    /**
381     * Sets the selected item position.
382     */
383    public void setSelectedPosition(int position) {
384        mSelectedPosition = position;
385        if(mGridViewHolder != null && mGridViewHolder.getGridView().getAdapter() != null) {
386            mGridViewHolder.getGridView().setSelectedPositionSmooth(position);
387        }
388    }
389
390    private void updateAdapter() {
391        if (mGridViewHolder != null) {
392            mGridPresenter.onBindViewHolder(mGridViewHolder, mAdapter);
393            if (mSelectedPosition != -1) {
394                mGridViewHolder.getGridView().setSelectedPosition(mSelectedPosition);
395            }
396        }
397    }
398}
399