1/* This file is auto-generated from BaseRowFragment.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.v4.app.Fragment;
19import android.os.Bundle;
20import android.support.v17.leanback.widget.ItemBridgeAdapter;
21import android.support.v17.leanback.widget.ListRow;
22import android.support.v17.leanback.widget.ObjectAdapter;
23import android.support.v17.leanback.widget.OnChildViewHolderSelectedListener;
24import android.support.v17.leanback.widget.PresenterSelector;
25import android.support.v17.leanback.widget.Row;
26import android.support.v17.leanback.widget.VerticalGridView;
27import android.support.v7.widget.RecyclerView;
28import android.view.LayoutInflater;
29import android.view.View;
30import android.view.ViewGroup;
31
32/**
33 * An internal base class for a fragment containing a list of rows.
34 */
35abstract class BaseRowSupportFragment extends Fragment {
36    private static final String CURRENT_SELECTED_POSITION = "currentSelectedPosition";
37    private ObjectAdapter mAdapter;
38    VerticalGridView mVerticalGridView;
39    private PresenterSelector mPresenterSelector;
40    ItemBridgeAdapter mBridgeAdapter;
41    int mSelectedPosition = -1;
42    private boolean mPendingTransitionPrepare;
43    private LateSelectionObserver mLateSelectionObserver = new LateSelectionObserver();
44
45    abstract int getLayoutResourceId();
46
47    private final OnChildViewHolderSelectedListener mRowSelectedListener =
48            new OnChildViewHolderSelectedListener() {
49                @Override
50                public void onChildViewHolderSelected(RecyclerView parent,
51                        RecyclerView.ViewHolder view, int position, int subposition) {
52                    mSelectedPosition = position;
53                    onRowSelected(parent, view, position, subposition);
54                }
55            };
56
57    void onRowSelected(RecyclerView parent, RecyclerView.ViewHolder view,
58            int position, int subposition) {
59    }
60
61    @Override
62    public View onCreateView(LayoutInflater inflater, ViewGroup container,
63            Bundle savedInstanceState) {
64        View view = inflater.inflate(getLayoutResourceId(), container, false);
65        mVerticalGridView = findGridViewFromRoot(view);
66        if (mPendingTransitionPrepare) {
67            mPendingTransitionPrepare = false;
68            onTransitionPrepare();
69        }
70        return view;
71    }
72
73    VerticalGridView findGridViewFromRoot(View view) {
74        return (VerticalGridView) view;
75    }
76
77    @Override
78    public void onViewCreated(View view, Bundle savedInstanceState) {
79        if (savedInstanceState != null) {
80            mSelectedPosition = savedInstanceState.getInt(CURRENT_SELECTED_POSITION, -1);
81        }
82        if (mBridgeAdapter != null) {
83            setAdapterAndSelection();
84        }
85        mVerticalGridView.setOnChildViewHolderSelectedListener(mRowSelectedListener);
86    }
87
88    /**
89     * This class waits for the adapter to be updated before setting the selected
90     * row.
91     */
92    private class LateSelectionObserver extends RecyclerView.AdapterDataObserver {
93        boolean mIsLateSelection = false;
94
95        LateSelectionObserver() {
96        }
97
98        @Override
99        public void onChanged() {
100            performLateSelection();
101        }
102
103        @Override
104        public void onItemRangeInserted(int positionStart, int itemCount) {
105            performLateSelection();
106        }
107
108        void startLateSelection() {
109            mIsLateSelection = true;
110            mBridgeAdapter.registerAdapterDataObserver(this);
111        }
112
113        void performLateSelection() {
114            clear();
115            if (mVerticalGridView != null) {
116                mVerticalGridView.setSelectedPosition(mSelectedPosition);
117            }
118        }
119
120        void clear() {
121            if (mIsLateSelection) {
122                mIsLateSelection = false;
123                mBridgeAdapter.unregisterAdapterDataObserver(this);
124            }
125        }
126    }
127
128    void setAdapterAndSelection() {
129        mVerticalGridView.setAdapter(mBridgeAdapter);
130        // We don't set the selected position unless we've data in the adapter.
131        boolean lateSelection = mBridgeAdapter.getItemCount() == 0 && mSelectedPosition >= 0;
132        if (lateSelection) {
133            mLateSelectionObserver.startLateSelection();
134        } else if (mSelectedPosition >= 0) {
135            mVerticalGridView.setSelectedPosition(mSelectedPosition);
136        }
137    }
138
139    @Override
140    public void onDestroyView() {
141        super.onDestroyView();
142        mLateSelectionObserver.clear();
143        mVerticalGridView = null;
144    }
145
146    @Override
147    public void onSaveInstanceState(Bundle outState) {
148        super.onSaveInstanceState(outState);
149        outState.putInt(CURRENT_SELECTED_POSITION, mSelectedPosition);
150    }
151
152    /**
153     * Set the presenter selector used to create and bind views.
154     */
155    public final void setPresenterSelector(PresenterSelector presenterSelector) {
156        mPresenterSelector = presenterSelector;
157        updateAdapter();
158    }
159
160    /**
161     * Get the presenter selector used to create and bind views.
162     */
163    public final PresenterSelector getPresenterSelector() {
164        return mPresenterSelector;
165    }
166
167    /**
168     * Sets the adapter for the fragment.
169     */
170    public final void setAdapter(ObjectAdapter rowsAdapter) {
171        mAdapter = rowsAdapter;
172        updateAdapter();
173    }
174
175    /**
176     * Returns the list of rows.
177     */
178    public final ObjectAdapter getAdapter() {
179        return mAdapter;
180    }
181
182    /**
183     * Returns the bridge adapter.
184     */
185    final ItemBridgeAdapter getBridgeAdapter() {
186        return mBridgeAdapter;
187    }
188
189    /**
190     * Sets the selected row position with smooth animation.
191     */
192    public void setSelectedPosition(int position) {
193        setSelectedPosition(position, true);
194    }
195
196    /**
197     * Gets position of currently selected row.
198     * @return Position of currently selected row.
199     */
200    public int getSelectedPosition() {
201        return mSelectedPosition;
202    }
203
204    /**
205     * Sets the selected row position.
206     */
207    public void setSelectedPosition(int position, boolean smooth) {
208        if (mSelectedPosition == position) {
209            return;
210        }
211        mSelectedPosition = position;
212        if(mVerticalGridView != null && mVerticalGridView.getAdapter() != null) {
213            if (mLateSelectionObserver.mIsLateSelection) {
214                return;
215            }
216            if (smooth) {
217                mVerticalGridView.setSelectedPositionSmooth(position);
218            } else {
219                mVerticalGridView.setSelectedPosition(position);
220            }
221        }
222    }
223
224    final VerticalGridView getVerticalGridView() {
225        return mVerticalGridView;
226    }
227
228    void updateAdapter() {
229        if (mBridgeAdapter != null) {
230            // detach observer from ObjectAdapter
231            mLateSelectionObserver.clear();
232            mBridgeAdapter.clear();
233            mBridgeAdapter = null;
234        }
235
236        if (mAdapter != null) {
237            // If presenter selector is null, adapter ps will be used
238            mBridgeAdapter = new ItemBridgeAdapter(mAdapter, mPresenterSelector);
239        }
240        if (mVerticalGridView != null) {
241            setAdapterAndSelection();
242        }
243    }
244
245    Object getItem(Row row, int position) {
246        if (row instanceof ListRow) {
247            return ((ListRow) row).getAdapter().get(position);
248        } else {
249            return null;
250        }
251    }
252
253    public boolean onTransitionPrepare() {
254        if (mVerticalGridView != null) {
255            mVerticalGridView.setAnimateChildLayout(false);
256            mVerticalGridView.setScrollEnabled(false);
257            return true;
258        }
259        mPendingTransitionPrepare = true;
260        return false;
261    }
262
263    public void onTransitionStart() {
264        if (mVerticalGridView != null) {
265            mVerticalGridView.setPruneChild(false);
266            mVerticalGridView.setLayoutFrozen(true);
267            mVerticalGridView.setFocusSearchDisabled(true);
268        }
269    }
270
271    public void onTransitionEnd() {
272        // be careful that fragment might be destroyed before header transition ends.
273        if (mVerticalGridView != null) {
274            mVerticalGridView.setLayoutFrozen(false);
275            mVerticalGridView.setAnimateChildLayout(true);
276            mVerticalGridView.setPruneChild(true);
277            mVerticalGridView.setFocusSearchDisabled(false);
278            mVerticalGridView.setScrollEnabled(true);
279        }
280    }
281
282    public void setAlignment(int windowAlignOffsetTop) {
283        if (mVerticalGridView != null) {
284            // align the top edge of item
285            mVerticalGridView.setItemAlignmentOffset(0);
286            mVerticalGridView.setItemAlignmentOffsetPercent(
287                    VerticalGridView.ITEM_ALIGN_OFFSET_PERCENT_DISABLED);
288
289            // align to a fixed position from top
290            mVerticalGridView.setWindowAlignmentOffset(windowAlignOffsetTop);
291            mVerticalGridView.setWindowAlignmentOffsetPercent(
292                    VerticalGridView.WINDOW_ALIGN_OFFSET_PERCENT_DISABLED);
293            mVerticalGridView.setWindowAlignment(VerticalGridView.WINDOW_ALIGN_NO_EDGE);
294        }
295    }
296}
297