161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu/*
261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Copyright (C) 2014 The Android Open Source Project
361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu *
461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * in compliance with the License. You may obtain a copy of the License at
661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu *
761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * http://www.apache.org/licenses/LICENSE-2.0
861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu *
961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Unless required by applicable law or agreed to in writing, software distributed under the License
1061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
1161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * or implied. See the License for the specific language governing permissions and limitations under
1261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * the License.
1361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */
14ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikaspackage androidx.leanback.app;
1561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu
1661905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.os.Bundle;
178619e0ef7062b6a714f22af993e4b440fae7ef08Aurimas Liutikasimport android.view.LayoutInflater;
188619e0ef7062b6a714f22af993e4b440fae7ef08Aurimas Liutikasimport android.view.View;
198619e0ef7062b6a714f22af993e4b440fae7ef08Aurimas Liutikasimport android.view.ViewGroup;
208619e0ef7062b6a714f22af993e4b440fae7ef08Aurimas Liutikas
21ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.annotation.NonNull;
22ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.annotation.Nullable;
238619e0ef7062b6a714f22af993e4b440fae7ef08Aurimas Liutikasimport androidx.fragment.app.Fragment;
24ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.leanback.widget.ItemBridgeAdapter;
25ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.leanback.widget.ListRow;
26ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.leanback.widget.ObjectAdapter;
27ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.leanback.widget.OnChildViewHolderSelectedListener;
28ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.leanback.widget.PresenterSelector;
29ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.leanback.widget.Row;
30ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.leanback.widget.VerticalGridView;
31ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.recyclerview.widget.RecyclerView;
3261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu
3361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu/**
3461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * An internal base class for a fragment containing a list of rows.
3561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */
3661905b0b52c50018dcaebcd79699c39b8f28d622Dake Guabstract class BaseRowSupportFragment extends Fragment {
37fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak    private static final String CURRENT_SELECTED_POSITION = "currentSelectedPosition";
3861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu    private ObjectAdapter mAdapter;
3999ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas    VerticalGridView mVerticalGridView;
4061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu    private PresenterSelector mPresenterSelector;
4150cf9ada93e50e906f20f5edf595234ada196d45Dake Gu    final ItemBridgeAdapter mBridgeAdapter = new ItemBridgeAdapter();
4299ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas    int mSelectedPosition = -1;
43902e68c114f86e8002516ff3f0248b722b6c5711Dake Gu    private boolean mPendingTransitionPrepare;
44bb0a680c10b84b83833a59634373140f8bd0750csusnata    private LateSelectionObserver mLateSelectionObserver = new LateSelectionObserver();
4561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu
4642752c860a26deacca04ea9ebeb00ddb4d8ce2fcDake Gu    abstract int getLayoutResourceId();
4761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu
480246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    private final OnChildViewHolderSelectedListener mRowSelectedListener =
490246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            new OnChildViewHolderSelectedListener() {
500246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                @Override
510246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                public void onChildViewHolderSelected(RecyclerView parent,
520246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                        RecyclerView.ViewHolder view, int position, int subposition) {
53514b6d101c6b7d4b7151cf8789424bde66fab511Dake Gu                    if (!mLateSelectionObserver.mIsLateSelection) {
54514b6d101c6b7d4b7151cf8789424bde66fab511Dake Gu                        mSelectedPosition = position;
55514b6d101c6b7d4b7151cf8789424bde66fab511Dake Gu                        onRowSelected(parent, view, position, subposition);
56514b6d101c6b7d4b7151cf8789424bde66fab511Dake Gu                    }
570246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                }
580246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            };
5961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu
600246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    void onRowSelected(RecyclerView parent, RecyclerView.ViewHolder view,
610246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            int position, int subposition) {
6261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu    }
6361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu
6461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu    @Override
6561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu    public View onCreateView(LayoutInflater inflater, ViewGroup container,
6661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu            Bundle savedInstanceState) {
6761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu        View view = inflater.inflate(getLayoutResourceId(), container, false);
6861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu        mVerticalGridView = findGridViewFromRoot(view);
69902e68c114f86e8002516ff3f0248b722b6c5711Dake Gu        if (mPendingTransitionPrepare) {
70902e68c114f86e8002516ff3f0248b722b6c5711Dake Gu            mPendingTransitionPrepare = false;
71902e68c114f86e8002516ff3f0248b722b6c5711Dake Gu            onTransitionPrepare();
72902e68c114f86e8002516ff3f0248b722b6c5711Dake Gu        }
7361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu        return view;
7461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu    }
7561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu
7642752c860a26deacca04ea9ebeb00ddb4d8ce2fcDake Gu    VerticalGridView findGridViewFromRoot(View view) {
7761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu        return (VerticalGridView) view;
7861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu    }
7961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu
8061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu    @Override
81cb3829a5ee01e3c0783019c04d083bde4d0082e8Jake Wharton    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
82fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak        if (savedInstanceState != null) {
83fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak            mSelectedPosition = savedInstanceState.getInt(CURRENT_SELECTED_POSITION, -1);
84fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak        }
8550cf9ada93e50e906f20f5edf595234ada196d45Dake Gu        setAdapterAndSelection();
86bb0a680c10b84b83833a59634373140f8bd0750csusnata        mVerticalGridView.setOnChildViewHolderSelectedListener(mRowSelectedListener);
87bb0a680c10b84b83833a59634373140f8bd0750csusnata    }
88bb0a680c10b84b83833a59634373140f8bd0750csusnata
89bb0a680c10b84b83833a59634373140f8bd0750csusnata    /**
90bb0a680c10b84b83833a59634373140f8bd0750csusnata     * This class waits for the adapter to be updated before setting the selected
91bb0a680c10b84b83833a59634373140f8bd0750csusnata     * row.
92bb0a680c10b84b83833a59634373140f8bd0750csusnata     */
93bb0a680c10b84b83833a59634373140f8bd0750csusnata    private class LateSelectionObserver extends RecyclerView.AdapterDataObserver {
94bb0a680c10b84b83833a59634373140f8bd0750csusnata        boolean mIsLateSelection = false;
95bb0a680c10b84b83833a59634373140f8bd0750csusnata
9699ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas        LateSelectionObserver() {
9799ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas        }
9899ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas
9915375aa6fd54b036f97f99229aefab2822c8a1c9Aurimas Liutikas        @Override
100bb0a680c10b84b83833a59634373140f8bd0750csusnata        public void onChanged() {
101bb0a680c10b84b83833a59634373140f8bd0750csusnata            performLateSelection();
102bb0a680c10b84b83833a59634373140f8bd0750csusnata        }
103bb0a680c10b84b83833a59634373140f8bd0750csusnata
10415375aa6fd54b036f97f99229aefab2822c8a1c9Aurimas Liutikas        @Override
105bb0a680c10b84b83833a59634373140f8bd0750csusnata        public void onItemRangeInserted(int positionStart, int itemCount) {
106bb0a680c10b84b83833a59634373140f8bd0750csusnata            performLateSelection();
107bb0a680c10b84b83833a59634373140f8bd0750csusnata        }
108bb0a680c10b84b83833a59634373140f8bd0750csusnata
109bb0a680c10b84b83833a59634373140f8bd0750csusnata        void startLateSelection() {
110bb0a680c10b84b83833a59634373140f8bd0750csusnata            mIsLateSelection = true;
111bb0a680c10b84b83833a59634373140f8bd0750csusnata            mBridgeAdapter.registerAdapterDataObserver(this);
112bb0a680c10b84b83833a59634373140f8bd0750csusnata        }
113bb0a680c10b84b83833a59634373140f8bd0750csusnata
114bb0a680c10b84b83833a59634373140f8bd0750csusnata        void performLateSelection() {
115bb0a680c10b84b83833a59634373140f8bd0750csusnata            clear();
116bb0a680c10b84b83833a59634373140f8bd0750csusnata            if (mVerticalGridView != null) {
11761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu                mVerticalGridView.setSelectedPosition(mSelectedPosition);
11861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu            }
11961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu        }
120bb0a680c10b84b83833a59634373140f8bd0750csusnata
121bb0a680c10b84b83833a59634373140f8bd0750csusnata        void clear() {
122bb0a680c10b84b83833a59634373140f8bd0750csusnata            if (mIsLateSelection) {
123bb0a680c10b84b83833a59634373140f8bd0750csusnata                mIsLateSelection = false;
124bb0a680c10b84b83833a59634373140f8bd0750csusnata                mBridgeAdapter.unregisterAdapterDataObserver(this);
125bb0a680c10b84b83833a59634373140f8bd0750csusnata            }
126bb0a680c10b84b83833a59634373140f8bd0750csusnata        }
127bb0a680c10b84b83833a59634373140f8bd0750csusnata    }
128bb0a680c10b84b83833a59634373140f8bd0750csusnata
129bb0a680c10b84b83833a59634373140f8bd0750csusnata    void setAdapterAndSelection() {
130c807587e03e775abb23f62894ad59bfb91cfbd97Dake Gu        if (mAdapter == null) {
131c807587e03e775abb23f62894ad59bfb91cfbd97Dake Gu            // delay until ItemBridgeAdapter has wrappedAdapter. Once we assign ItemBridgeAdapter
132c807587e03e775abb23f62894ad59bfb91cfbd97Dake Gu            // to RecyclerView, it will not be allowed to change "hasStableId" to true.
133c807587e03e775abb23f62894ad59bfb91cfbd97Dake Gu            return;
134c807587e03e775abb23f62894ad59bfb91cfbd97Dake Gu        }
135c807587e03e775abb23f62894ad59bfb91cfbd97Dake Gu        if (mVerticalGridView.getAdapter() != mBridgeAdapter) {
136c807587e03e775abb23f62894ad59bfb91cfbd97Dake Gu            // avoid extra layout if ItemBridgeAdapter was already set.
137c807587e03e775abb23f62894ad59bfb91cfbd97Dake Gu            mVerticalGridView.setAdapter(mBridgeAdapter);
138c807587e03e775abb23f62894ad59bfb91cfbd97Dake Gu        }
139bb0a680c10b84b83833a59634373140f8bd0750csusnata        // We don't set the selected position unless we've data in the adapter.
140bb0a680c10b84b83833a59634373140f8bd0750csusnata        boolean lateSelection = mBridgeAdapter.getItemCount() == 0 && mSelectedPosition >= 0;
141bb0a680c10b84b83833a59634373140f8bd0750csusnata        if (lateSelection) {
142bb0a680c10b84b83833a59634373140f8bd0750csusnata            mLateSelectionObserver.startLateSelection();
143bb0a680c10b84b83833a59634373140f8bd0750csusnata        } else if (mSelectedPosition >= 0) {
144bb0a680c10b84b83833a59634373140f8bd0750csusnata            mVerticalGridView.setSelectedPosition(mSelectedPosition);
145bb0a680c10b84b83833a59634373140f8bd0750csusnata        }
14661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu    }
14761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu
14861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu    @Override
14961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu    public void onDestroyView() {
15061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu        super.onDestroyView();
151bb0a680c10b84b83833a59634373140f8bd0750csusnata        mLateSelectionObserver.clear();
15261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu        mVerticalGridView = null;
15361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu    }
15461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu
155fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak    @Override
156fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak    public void onSaveInstanceState(Bundle outState) {
157fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak        super.onSaveInstanceState(outState);
158fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak        outState.putInt(CURRENT_SELECTED_POSITION, mSelectedPosition);
159fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak    }
160fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak
16161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu    /**
16261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu     * Set the presenter selector used to create and bind views.
16361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu     */
16461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu    public final void setPresenterSelector(PresenterSelector presenterSelector) {
165e40904288950bc692751a30fcec42cfc4d03ff58Dake Gu        if (mPresenterSelector != presenterSelector) {
166e40904288950bc692751a30fcec42cfc4d03ff58Dake Gu            mPresenterSelector = presenterSelector;
167e40904288950bc692751a30fcec42cfc4d03ff58Dake Gu            updateAdapter();
168e40904288950bc692751a30fcec42cfc4d03ff58Dake Gu        }
16961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu    }
17061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu
17161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu    /**
17261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu     * Get the presenter selector used to create and bind views.
17361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu     */
17461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu    public final PresenterSelector getPresenterSelector() {
17561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu        return mPresenterSelector;
17661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu    }
17761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu
17861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu    /**
179c807587e03e775abb23f62894ad59bfb91cfbd97Dake Gu     * Sets the adapter that represents a list of rows.
180c807587e03e775abb23f62894ad59bfb91cfbd97Dake Gu     * @param rowsAdapter Adapter that represents list of rows.
18161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu     */
18261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu    public final void setAdapter(ObjectAdapter rowsAdapter) {
183e40904288950bc692751a30fcec42cfc4d03ff58Dake Gu        if (mAdapter != rowsAdapter) {
184e40904288950bc692751a30fcec42cfc4d03ff58Dake Gu            mAdapter = rowsAdapter;
185e40904288950bc692751a30fcec42cfc4d03ff58Dake Gu            updateAdapter();
186e40904288950bc692751a30fcec42cfc4d03ff58Dake Gu        }
18761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu    }
18861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu
18961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu    /**
190c807587e03e775abb23f62894ad59bfb91cfbd97Dake Gu     * Returns the Adapter that represents list of rows.
191c807587e03e775abb23f62894ad59bfb91cfbd97Dake Gu     * @return Adapter that represents list of rows.
19261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu     */
19361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu    public final ObjectAdapter getAdapter() {
19461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu        return mAdapter;
19561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu    }
19661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu
19761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu    /**
198c807587e03e775abb23f62894ad59bfb91cfbd97Dake Gu     * Returns the RecyclerView.Adapter that wraps {@link #getAdapter()}.
199c807587e03e775abb23f62894ad59bfb91cfbd97Dake Gu     * @return The RecyclerView.Adapter that wraps {@link #getAdapter()}.
20061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu     */
201c807587e03e775abb23f62894ad59bfb91cfbd97Dake Gu    public final ItemBridgeAdapter getBridgeAdapter() {
20261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu        return mBridgeAdapter;
20361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu    }
20461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu
20561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu    /**
2063f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu     * Sets the selected row position with smooth animation.
20761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu     */
20861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu    public void setSelectedPosition(int position) {
2093f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu        setSelectedPosition(position, true);
2103f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu    }
2113f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu
2123f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu    /**
2130d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu     * Gets position of currently selected row.
2140d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu     * @return Position of currently selected row.
2150d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu     */
2162f1bd591e01fe93f605844d4a10cde7116315b7cDake Gu    public int getSelectedPosition() {
2170d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu        return mSelectedPosition;
2180d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu    }
2190d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu
2200d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu    /**
2213f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu     * Sets the selected row position.
2223f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu     */
2233f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu    public void setSelectedPosition(int position, boolean smooth) {
2240d841b3454f896da58deb506ca22730bfd04f34fDake Gu        if (mSelectedPosition == position) {
2250d841b3454f896da58deb506ca22730bfd04f34fDake Gu            return;
2260d841b3454f896da58deb506ca22730bfd04f34fDake Gu        }
22761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu        mSelectedPosition = position;
22850cf9ada93e50e906f20f5edf595234ada196d45Dake Gu        if (mVerticalGridView != null) {
229bb0a680c10b84b83833a59634373140f8bd0750csusnata            if (mLateSelectionObserver.mIsLateSelection) {
230bb0a680c10b84b83833a59634373140f8bd0750csusnata                return;
231bb0a680c10b84b83833a59634373140f8bd0750csusnata            }
2323f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu            if (smooth) {
2333f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu                mVerticalGridView.setSelectedPositionSmooth(position);
2343f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu            } else {
2353f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu                mVerticalGridView.setSelectedPosition(position);
2363f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu            }
23761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu        }
23861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu    }
23961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu
240935b033edfd9d03129fce6a5b7a1d3a327b74f91susnata    public final VerticalGridView getVerticalGridView() {
24161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu        return mVerticalGridView;
24261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu    }
24361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu
24442752c860a26deacca04ea9ebeb00ddb4d8ce2fcDake Gu    void updateAdapter() {
24550cf9ada93e50e906f20f5edf595234ada196d45Dake Gu        mBridgeAdapter.setAdapter(mAdapter);
24650cf9ada93e50e906f20f5edf595234ada196d45Dake Gu        mBridgeAdapter.setPresenter(mPresenterSelector);
24761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu
24861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu        if (mVerticalGridView != null) {
249bb0a680c10b84b83833a59634373140f8bd0750csusnata            setAdapterAndSelection();
25061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu        }
25161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu    }
25261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu
25342752c860a26deacca04ea9ebeb00ddb4d8ce2fcDake Gu    Object getItem(Row row, int position) {
25461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu        if (row instanceof ListRow) {
25561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu            return ((ListRow) row).getAdapter().get(position);
25661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu        } else {
25761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu            return null;
25861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu        }
25961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu    }
26061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu
2612f5ebf3f6f7bb6a24856f389e369b247118ba119susnata    public boolean onTransitionPrepare() {
26261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu        if (mVerticalGridView != null) {
26361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu            mVerticalGridView.setAnimateChildLayout(false);
264902e68c114f86e8002516ff3f0248b722b6c5711Dake Gu            mVerticalGridView.setScrollEnabled(false);
265902e68c114f86e8002516ff3f0248b722b6c5711Dake Gu            return true;
26661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu        }
267902e68c114f86e8002516ff3f0248b722b6c5711Dake Gu        mPendingTransitionPrepare = true;
268902e68c114f86e8002516ff3f0248b722b6c5711Dake Gu        return false;
269902e68c114f86e8002516ff3f0248b722b6c5711Dake Gu    }
270902e68c114f86e8002516ff3f0248b722b6c5711Dake Gu
2712f5ebf3f6f7bb6a24856f389e369b247118ba119susnata    public void onTransitionStart() {
2724a4e0872bdf0548188e81740eb62085215e7f976Dake Gu        if (mVerticalGridView != null) {
2734a4e0872bdf0548188e81740eb62085215e7f976Dake Gu            mVerticalGridView.setPruneChild(false);
2744a4e0872bdf0548188e81740eb62085215e7f976Dake Gu            mVerticalGridView.setLayoutFrozen(true);
2754a4e0872bdf0548188e81740eb62085215e7f976Dake Gu            mVerticalGridView.setFocusSearchDisabled(true);
2764a4e0872bdf0548188e81740eb62085215e7f976Dake Gu        }
27761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu    }
27861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu
2792f5ebf3f6f7bb6a24856f389e369b247118ba119susnata    public void onTransitionEnd() {
2804a4e0872bdf0548188e81740eb62085215e7f976Dake Gu        // be careful that fragment might be destroyed before header transition ends.
2814a4e0872bdf0548188e81740eb62085215e7f976Dake Gu        if (mVerticalGridView != null) {
2824a4e0872bdf0548188e81740eb62085215e7f976Dake Gu            mVerticalGridView.setLayoutFrozen(false);
2834a4e0872bdf0548188e81740eb62085215e7f976Dake Gu            mVerticalGridView.setAnimateChildLayout(true);
2844a4e0872bdf0548188e81740eb62085215e7f976Dake Gu            mVerticalGridView.setPruneChild(true);
2854a4e0872bdf0548188e81740eb62085215e7f976Dake Gu            mVerticalGridView.setFocusSearchDisabled(false);
2864a4e0872bdf0548188e81740eb62085215e7f976Dake Gu            mVerticalGridView.setScrollEnabled(true);
2874a4e0872bdf0548188e81740eb62085215e7f976Dake Gu        }
28861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu    }
28961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu
2902f5ebf3f6f7bb6a24856f389e369b247118ba119susnata    public void setAlignment(int windowAlignOffsetTop) {
29161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu        if (mVerticalGridView != null) {
29261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu            // align the top edge of item
29361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu            mVerticalGridView.setItemAlignmentOffset(0);
29461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu            mVerticalGridView.setItemAlignmentOffsetPercent(
29561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu                    VerticalGridView.ITEM_ALIGN_OFFSET_PERCENT_DISABLED);
29661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu
29761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu            // align to a fixed position from top
2982f5ebf3f6f7bb6a24856f389e369b247118ba119susnata            mVerticalGridView.setWindowAlignmentOffset(windowAlignOffsetTop);
29961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu            mVerticalGridView.setWindowAlignmentOffsetPercent(
30061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu                    VerticalGridView.WINDOW_ALIGN_OFFSET_PERCENT_DISABLED);
30161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu            mVerticalGridView.setWindowAlignment(VerticalGridView.WINDOW_ALIGN_NO_EDGE);
30261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu        }
30361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu    }
30461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu}
305