BaseRowSupportFragment.java revision 935b033edfd9d03129fce6a5b7a1d3a327b74f91
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    private VerticalGridView mVerticalGridView;
39    private PresenterSelector mPresenterSelector;
40    private ItemBridgeAdapter mBridgeAdapter;
41    private 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        @Override
96        public void onChanged() {
97            performLateSelection();
98        }
99
100        @Override
101        public void onItemRangeInserted(int positionStart, int itemCount) {
102            performLateSelection();
103        }
104
105        void startLateSelection() {
106            mIsLateSelection = true;
107            mBridgeAdapter.registerAdapterDataObserver(this);
108        }
109
110        void performLateSelection() {
111            clear();
112            if (mVerticalGridView != null) {
113                mVerticalGridView.setSelectedPosition(mSelectedPosition);
114            }
115        }
116
117        void clear() {
118            if (mIsLateSelection) {
119                mIsLateSelection = false;
120                mBridgeAdapter.unregisterAdapterDataObserver(this);
121            }
122        }
123    }
124
125    void setAdapterAndSelection() {
126        mVerticalGridView.setAdapter(mBridgeAdapter);
127        // We don't set the selected position unless we've data in the adapter.
128        boolean lateSelection = mBridgeAdapter.getItemCount() == 0 && mSelectedPosition >= 0;
129        if (lateSelection) {
130            mLateSelectionObserver.startLateSelection();
131        } else if (mSelectedPosition >= 0) {
132            mVerticalGridView.setSelectedPosition(mSelectedPosition);
133        }
134    }
135
136    @Override
137    public void onDestroyView() {
138        super.onDestroyView();
139        mLateSelectionObserver.clear();
140        mVerticalGridView = null;
141    }
142
143    @Override
144    public void onSaveInstanceState(Bundle outState) {
145        super.onSaveInstanceState(outState);
146        outState.putInt(CURRENT_SELECTED_POSITION, mSelectedPosition);
147    }
148
149    /**
150     * Set the presenter selector used to create and bind views.
151     */
152    public final void setPresenterSelector(PresenterSelector presenterSelector) {
153        mPresenterSelector = presenterSelector;
154        updateAdapter();
155    }
156
157    /**
158     * Get the presenter selector used to create and bind views.
159     */
160    public final PresenterSelector getPresenterSelector() {
161        return mPresenterSelector;
162    }
163
164    /**
165     * Sets the adapter for the fragment.
166     */
167    public final void setAdapter(ObjectAdapter rowsAdapter) {
168        mAdapter = rowsAdapter;
169        updateAdapter();
170    }
171
172    /**
173     * Returns the list of rows.
174     */
175    public final ObjectAdapter getAdapter() {
176        return mAdapter;
177    }
178
179    /**
180     * Returns the bridge adapter.
181     */
182    final ItemBridgeAdapter getBridgeAdapter() {
183        return mBridgeAdapter;
184    }
185
186    /**
187     * Sets the selected row position with smooth animation.
188     */
189    public void setSelectedPosition(int position) {
190        setSelectedPosition(position, true);
191    }
192
193    /**
194     * Gets position of currently selected row.
195     * @return Position of currently selected row.
196     */
197    public int getSelectedPosition() {
198        return mSelectedPosition;
199    }
200
201    /**
202     * Sets the selected row position.
203     */
204    public void setSelectedPosition(int position, boolean smooth) {
205        if (mSelectedPosition == position) {
206            return;
207        }
208        mSelectedPosition = position;
209        if(mVerticalGridView != null && mVerticalGridView.getAdapter() != null) {
210            if (mLateSelectionObserver.mIsLateSelection) {
211                return;
212            }
213            if (smooth) {
214                mVerticalGridView.setSelectedPositionSmooth(position);
215            } else {
216                mVerticalGridView.setSelectedPosition(position);
217            }
218        }
219    }
220
221    public final VerticalGridView getVerticalGridView() {
222        return mVerticalGridView;
223    }
224
225    void updateAdapter() {
226        if (mBridgeAdapter != null) {
227            // detach observer from ObjectAdapter
228            mLateSelectionObserver.clear();
229            mBridgeAdapter.clear();
230            mBridgeAdapter = null;
231        }
232
233        if (mAdapter != null) {
234            // If presenter selector is null, adapter ps will be used
235            mBridgeAdapter = new ItemBridgeAdapter(mAdapter, mPresenterSelector);
236        }
237        if (mVerticalGridView != null) {
238            setAdapterAndSelection();
239        }
240    }
241
242    Object getItem(Row row, int position) {
243        if (row instanceof ListRow) {
244            return ((ListRow) row).getAdapter().get(position);
245        } else {
246            return null;
247        }
248    }
249
250    public boolean onTransitionPrepare() {
251        if (mVerticalGridView != null) {
252            mVerticalGridView.setAnimateChildLayout(false);
253            mVerticalGridView.setScrollEnabled(false);
254            return true;
255        }
256        mPendingTransitionPrepare = true;
257        return false;
258    }
259
260    public void onTransitionStart() {
261        if (mVerticalGridView != null) {
262            mVerticalGridView.setPruneChild(false);
263            mVerticalGridView.setLayoutFrozen(true);
264            mVerticalGridView.setFocusSearchDisabled(true);
265        }
266    }
267
268    public void onTransitionEnd() {
269        // be careful that fragment might be destroyed before header transition ends.
270        if (mVerticalGridView != null) {
271            mVerticalGridView.setLayoutFrozen(false);
272            mVerticalGridView.setAnimateChildLayout(true);
273            mVerticalGridView.setPruneChild(true);
274            mVerticalGridView.setFocusSearchDisabled(false);
275            mVerticalGridView.setScrollEnabled(true);
276        }
277    }
278
279    public void setAlignment(int windowAlignOffsetTop) {
280        if (mVerticalGridView != null) {
281            // align the top edge of item
282            mVerticalGridView.setItemAlignmentOffset(0);
283            mVerticalGridView.setItemAlignmentOffsetPercent(
284                    VerticalGridView.ITEM_ALIGN_OFFSET_PERCENT_DISABLED);
285
286            // align to a fixed position from top
287            mVerticalGridView.setWindowAlignmentOffset(windowAlignOffsetTop);
288            mVerticalGridView.setWindowAlignmentOffsetPercent(
289                    VerticalGridView.WINDOW_ALIGN_OFFSET_PERCENT_DISABLED);
290            mVerticalGridView.setWindowAlignment(VerticalGridView.WINDOW_ALIGN_NO_EDGE);
291        }
292    }
293}
294