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
15package android.support.v17.leanback.supportleanbackshowcase.app.page;
16
17import android.app.Fragment;
18import android.os.Bundle;
19import android.support.v17.leanback.app.BrowseFragment;
20import android.support.v17.leanback.supportleanbackshowcase.R;
21import android.support.v17.leanback.transition.TransitionHelper;
22import android.support.v17.leanback.widget.ObjectAdapter;
23import android.support.v17.leanback.widget.OnChildLaidOutListener;
24import android.support.v17.leanback.widget.OnItemViewClickedListener;
25import android.support.v17.leanback.widget.OnItemViewSelectedListener;
26import android.support.v17.leanback.widget.Presenter;
27import android.support.v17.leanback.widget.Row;
28import android.support.v17.leanback.widget.RowPresenter;
29import android.support.v17.leanback.widget.VerticalGridPresenter;
30import android.util.Log;
31import android.view.LayoutInflater;
32import android.view.View;
33import android.view.ViewGroup;
34
35/**
36 * A fragment for rendering items in a vertical grids.
37 */
38public 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     */
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     */
73    public VerticalGridPresenter getGridPresenter() {
74        return mGridPresenter;
75    }
76
77    /**
78     * Sets the object adapter for the fragment.
79     */
80    public void setAdapter(ObjectAdapter adapter) {
81        mAdapter = adapter;
82        updateAdapter();
83    }
84
85    /**
86     * Returns the object adapter.
87     */
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     */
120    public void setOnItemViewSelectedListener(OnItemViewSelectedListener listener) {
121        mOnItemViewSelectedListener = listener;
122    }
123
124    private void gridOnItemSelected(int position) {
125        if (position != mSelectedPosition) {
126            mSelectedPosition = position;
127            showOrHideTitle();
128        }
129    }
130
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     */
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     */
156    public OnItemViewClickedListener getOnItemViewClickedListener() {
157        return mOnItemViewClickedListener;
158    }
159
160    @Override
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
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
187    public void onDestroyView() {
188        super.onDestroyView();
189        mGridViewHolder = null;
190    }
191
192    @Override
193    public BrowseFragment.MainFragmentAdapter getMainFragmentAdapter() {
194        return mMainFragmentAdapter;
195    }
196
197    /**
198     * Sets the selected item position.
199     */
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
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
216    void setEntranceTransitionState(boolean afterTransition) {
217        mGridPresenter.setEntranceTransitionState(mGridViewHolder, afterTransition);
218    }
219}
220