1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5  * in compliance with the License. You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software distributed under the License
10  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11  * or implied. See the License for the specific language governing permissions and limitations under
12  * the License.
13  */
14 
15 package android.support.v17.leanback.supportleanbackshowcase.app.page;
16 
17 import android.app.Fragment;
18 import android.os.Bundle;
19 import android.support.v17.leanback.app.BrowseFragment;
20 import android.support.v17.leanback.supportleanbackshowcase.R;
21 import android.support.v17.leanback.transition.TransitionHelper;
22 import android.support.v17.leanback.widget.ObjectAdapter;
23 import android.support.v17.leanback.widget.OnChildLaidOutListener;
24 import android.support.v17.leanback.widget.OnItemViewClickedListener;
25 import android.support.v17.leanback.widget.OnItemViewSelectedListener;
26 import android.support.v17.leanback.widget.Presenter;
27 import android.support.v17.leanback.widget.Row;
28 import android.support.v17.leanback.widget.RowPresenter;
29 import android.support.v17.leanback.widget.VerticalGridPresenter;
30 import android.util.Log;
31 import android.view.LayoutInflater;
32 import android.view.View;
33 import android.view.ViewGroup;
34 
35 /**
36  * A fragment for rendering items in a vertical grids.
37  */
38 public class GridFragment extends Fragment implements BrowseFragment.MainFragmentAdapterProvider {
39     private static final String TAG = "VerticalGridFragment";
40     private static boolean DEBUG = false;
41 
42     private ObjectAdapter mAdapter;
43     private VerticalGridPresenter mGridPresenter;
44     private VerticalGridPresenter.ViewHolder mGridViewHolder;
45     private OnItemViewSelectedListener mOnItemViewSelectedListener;
46     private OnItemViewClickedListener mOnItemViewClickedListener;
47     private Object mSceneAfterEntranceTransition;
48     private int mSelectedPosition = -1;
49     private BrowseFragment.MainFragmentAdapter mMainFragmentAdapter =
50             new BrowseFragment.MainFragmentAdapter(this) {
51                 @Override
52                 public void setEntranceTransitionState(boolean state) {
53                     GridFragment.this.setEntranceTransitionState(state);
54                 }
55             };
56     /**
57      * Sets the grid presenter.
58      */
setGridPresenter(VerticalGridPresenter gridPresenter)59     public void setGridPresenter(VerticalGridPresenter gridPresenter) {
60         if (gridPresenter == null) {
61             throw new IllegalArgumentException("Grid presenter may not be null");
62         }
63         mGridPresenter = gridPresenter;
64         mGridPresenter.setOnItemViewSelectedListener(mViewSelectedListener);
65         if (mOnItemViewClickedListener != null) {
66             mGridPresenter.setOnItemViewClickedListener(mOnItemViewClickedListener);
67         }
68     }
69 
70     /**
71      * Returns the grid presenter.
72      */
getGridPresenter()73     public VerticalGridPresenter getGridPresenter() {
74         return mGridPresenter;
75     }
76 
77     /**
78      * Sets the object adapter for the fragment.
79      */
setAdapter(ObjectAdapter adapter)80     public void setAdapter(ObjectAdapter adapter) {
81         mAdapter = adapter;
82         updateAdapter();
83     }
84 
85     /**
86      * Returns the object adapter.
87      */
getAdapter()88     public ObjectAdapter getAdapter() {
89         return mAdapter;
90     }
91 
92     final private OnItemViewSelectedListener mViewSelectedListener =
93             new OnItemViewSelectedListener() {
94                 @Override
95                 public void onItemSelected(Presenter.ViewHolder itemViewHolder, Object item,
96                                            RowPresenter.ViewHolder rowViewHolder, Row row) {
97                     int position = mGridViewHolder.getGridView().getSelectedPosition();
98                     if (DEBUG) Log.v(TAG, "grid selected position " + position);
99                     gridOnItemSelected(position);
100                     if (mOnItemViewSelectedListener != null) {
101                         mOnItemViewSelectedListener.onItemSelected(itemViewHolder, item,
102                                 rowViewHolder, row);
103                     }
104                 }
105             };
106 
107     final private OnChildLaidOutListener mChildLaidOutListener =
108             new OnChildLaidOutListener() {
109                 @Override
110                 public void onChildLaidOut(ViewGroup parent, View view, int position, long id) {
111                     if (position == 0) {
112                         showOrHideTitle();
113                     }
114                 }
115             };
116 
117     /**
118      * Sets an item selection listener.
119      */
setOnItemViewSelectedListener(OnItemViewSelectedListener listener)120     public void setOnItemViewSelectedListener(OnItemViewSelectedListener listener) {
121         mOnItemViewSelectedListener = listener;
122     }
123 
gridOnItemSelected(int position)124     private void gridOnItemSelected(int position) {
125         if (position != mSelectedPosition) {
126             mSelectedPosition = position;
127             showOrHideTitle();
128         }
129     }
130 
showOrHideTitle()131     private void showOrHideTitle() {
132         if (mGridViewHolder.getGridView().findViewHolderForAdapterPosition(mSelectedPosition)
133                 == null) {
134             return;
135         }
136         if (!mGridViewHolder.getGridView().hasPreviousViewInSameRow(mSelectedPosition)) {
137             mMainFragmentAdapter.getFragmentHost().showTitleView(true);
138         } else {
139             mMainFragmentAdapter.getFragmentHost().showTitleView(false);
140         }
141     }
142 
143     /**
144      * Sets an item clicked listener.
145      */
setOnItemViewClickedListener(OnItemViewClickedListener listener)146     public void setOnItemViewClickedListener(OnItemViewClickedListener listener) {
147         mOnItemViewClickedListener = listener;
148         if (mGridPresenter != null) {
149             mGridPresenter.setOnItemViewClickedListener(mOnItemViewClickedListener);
150         }
151     }
152 
153     /**
154      * Returns the item clicked listener.
155      */
getOnItemViewClickedListener()156     public OnItemViewClickedListener getOnItemViewClickedListener() {
157         return mOnItemViewClickedListener;
158     }
159 
160     @Override
onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)161     public View onCreateView(LayoutInflater inflater, ViewGroup container,
162                              Bundle savedInstanceState) {
163         return inflater.inflate(R.layout.grid_fragment, container, false);
164     }
165 
166     @Override
onViewCreated(View view, Bundle savedInstanceState)167     public void onViewCreated(View view, Bundle savedInstanceState) {
168         super.onViewCreated(view, savedInstanceState);
169         ViewGroup gridDock = (ViewGroup) view.findViewById(R.id.browse_grid_dock);
170         mGridViewHolder = mGridPresenter.onCreateViewHolder(gridDock);
171         gridDock.addView(mGridViewHolder.view);
172         mGridViewHolder.getGridView().setOnChildLaidOutListener(mChildLaidOutListener);
173 
174         mSceneAfterEntranceTransition = TransitionHelper.createScene(gridDock, new Runnable() {
175             @Override
176             public void run() {
177                 setEntranceTransitionState(true);
178             }
179         });
180 
181         getMainFragmentAdapter().getFragmentHost().notifyViewCreated(mMainFragmentAdapter);
182         updateAdapter();
183 
184     }
185 
186     @Override
onDestroyView()187     public void onDestroyView() {
188         super.onDestroyView();
189         mGridViewHolder = null;
190     }
191 
192     @Override
getMainFragmentAdapter()193     public BrowseFragment.MainFragmentAdapter getMainFragmentAdapter() {
194         return mMainFragmentAdapter;
195     }
196 
197     /**
198      * Sets the selected item position.
199      */
setSelectedPosition(int position)200     public void setSelectedPosition(int position) {
201         mSelectedPosition = position;
202         if(mGridViewHolder != null && mGridViewHolder.getGridView().getAdapter() != null) {
203             mGridViewHolder.getGridView().setSelectedPositionSmooth(position);
204         }
205     }
206 
updateAdapter()207     private void updateAdapter() {
208         if (mGridViewHolder != null) {
209             mGridPresenter.onBindViewHolder(mGridViewHolder, mAdapter);
210             if (mSelectedPosition != -1) {
211                 mGridViewHolder.getGridView().setSelectedPosition(mSelectedPosition);
212             }
213         }
214     }
215 
setEntranceTransitionState(boolean afterTransition)216     void setEntranceTransitionState(boolean afterTransition) {
217         mGridPresenter.setEntranceTransitionState(mGridViewHolder, afterTransition);
218     }
219 }
220