155c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout/*
255c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout * Copyright (C) 2014 The Android Open Source Project
355c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout *
455c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
555c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout * in compliance with the License. You may obtain a copy of the License at
655c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout *
755c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout * http://www.apache.org/licenses/LICENSE-2.0
855c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout *
955c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout * Unless required by applicable law or agreed to in writing, software distributed under the License
1055c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
1155c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout * or implied. See the License for the specific language governing permissions and limitations under
1255c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout * the License.
1355c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout */
1455c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stoutpackage android.support.v17.leanback.app;
1555c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout
1655c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stoutimport android.app.Fragment;
1755c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stoutimport android.os.Bundle;
1855c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stoutimport android.support.v17.leanback.widget.ItemBridgeAdapter;
1955c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stoutimport android.support.v17.leanback.widget.ListRow;
202f5ebf3f6f7bb6a24856f389e369b247118ba119susnataimport android.support.v17.leanback.widget.ObjectAdapter;
210246318f27a905a31df5a8af445cfe67d31dfb68Dake Guimport android.support.v17.leanback.widget.OnChildViewHolderSelectedListener;
222f5ebf3f6f7bb6a24856f389e369b247118ba119susnataimport android.support.v17.leanback.widget.PresenterSelector;
232f5ebf3f6f7bb6a24856f389e369b247118ba119susnataimport android.support.v17.leanback.widget.Row;
242f5ebf3f6f7bb6a24856f389e369b247118ba119susnataimport android.support.v17.leanback.widget.VerticalGridView;
250246318f27a905a31df5a8af445cfe67d31dfb68Dake Guimport android.support.v7.widget.RecyclerView;
2655c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stoutimport android.view.LayoutInflater;
2755c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stoutimport android.view.View;
2855c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stoutimport android.view.ViewGroup;
2955c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout
3055c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout/**
31a8a3b898da49324e83ea32c3f08776a481312166Tim Kilbourn * An internal base class for a fragment containing a list of rows.
3255c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout */
3355c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stoutabstract class BaseRowFragment extends Fragment {
34fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak    private static final String CURRENT_SELECTED_POSITION = "currentSelectedPosition";
3555c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout    private ObjectAdapter mAdapter;
36a8a3b898da49324e83ea32c3f08776a481312166Tim Kilbourn    private VerticalGridView mVerticalGridView;
3755c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout    private PresenterSelector mPresenterSelector;
3855c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout    private ItemBridgeAdapter mBridgeAdapter;
3955c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout    private int mSelectedPosition = -1;
40902e68c114f86e8002516ff3f0248b722b6c5711Dake Gu    private boolean mPendingTransitionPrepare;
41bb0a680c10b84b83833a59634373140f8bd0750csusnata    private LateSelectionObserver mLateSelectionObserver = new LateSelectionObserver();
4255c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout
4342752c860a26deacca04ea9ebeb00ddb4d8ce2fcDake Gu    abstract int getLayoutResourceId();
4455c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout
450246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    private final OnChildViewHolderSelectedListener mRowSelectedListener =
460246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            new OnChildViewHolderSelectedListener() {
470246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                @Override
480246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                public void onChildViewHolderSelected(RecyclerView parent,
490246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                        RecyclerView.ViewHolder view, int position, int subposition) {
500d841b3454f896da58deb506ca22730bfd04f34fDake Gu                    mSelectedPosition = position;
510246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                    onRowSelected(parent, view, position, subposition);
520246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu                }
530246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            };
5455c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout
550246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu    void onRowSelected(RecyclerView parent, RecyclerView.ViewHolder view,
560246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu            int position, int subposition) {
5755c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout    }
5855c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout
5955c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout    @Override
607a208cd35be79a69b1f4f36724b85ab96eb23e75Dake Gu    public View onCreateView(LayoutInflater inflater, ViewGroup container,
617a208cd35be79a69b1f4f36724b85ab96eb23e75Dake Gu            Bundle savedInstanceState) {
627a208cd35be79a69b1f4f36724b85ab96eb23e75Dake Gu        View view = inflater.inflate(getLayoutResourceId(), container, false);
637a208cd35be79a69b1f4f36724b85ab96eb23e75Dake Gu        mVerticalGridView = findGridViewFromRoot(view);
64902e68c114f86e8002516ff3f0248b722b6c5711Dake Gu        if (mPendingTransitionPrepare) {
65902e68c114f86e8002516ff3f0248b722b6c5711Dake Gu            mPendingTransitionPrepare = false;
66902e68c114f86e8002516ff3f0248b722b6c5711Dake Gu            onTransitionPrepare();
67902e68c114f86e8002516ff3f0248b722b6c5711Dake Gu        }
687a208cd35be79a69b1f4f36724b85ab96eb23e75Dake Gu        return view;
697a208cd35be79a69b1f4f36724b85ab96eb23e75Dake Gu    }
707a208cd35be79a69b1f4f36724b85ab96eb23e75Dake Gu
7142752c860a26deacca04ea9ebeb00ddb4d8ce2fcDake Gu    VerticalGridView findGridViewFromRoot(View view) {
727a208cd35be79a69b1f4f36724b85ab96eb23e75Dake Gu        return (VerticalGridView) view;
7355c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout    }
7455c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout
7555c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout    @Override
7655c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout    public void onViewCreated(View view, Bundle savedInstanceState) {
77fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak        if (savedInstanceState != null) {
78fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak            mSelectedPosition = savedInstanceState.getInt(CURRENT_SELECTED_POSITION, -1);
79fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak        }
8055c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout        if (mBridgeAdapter != null) {
81bb0a680c10b84b83833a59634373140f8bd0750csusnata            setAdapterAndSelection();
82bb0a680c10b84b83833a59634373140f8bd0750csusnata        }
83bb0a680c10b84b83833a59634373140f8bd0750csusnata        mVerticalGridView.setOnChildViewHolderSelectedListener(mRowSelectedListener);
84bb0a680c10b84b83833a59634373140f8bd0750csusnata    }
85bb0a680c10b84b83833a59634373140f8bd0750csusnata
86bb0a680c10b84b83833a59634373140f8bd0750csusnata    /**
87bb0a680c10b84b83833a59634373140f8bd0750csusnata     * This class waits for the adapter to be updated before setting the selected
88bb0a680c10b84b83833a59634373140f8bd0750csusnata     * row.
89bb0a680c10b84b83833a59634373140f8bd0750csusnata     */
90bb0a680c10b84b83833a59634373140f8bd0750csusnata    private class LateSelectionObserver extends RecyclerView.AdapterDataObserver {
91bb0a680c10b84b83833a59634373140f8bd0750csusnata        boolean mIsLateSelection = false;
92bb0a680c10b84b83833a59634373140f8bd0750csusnata
93bb0a680c10b84b83833a59634373140f8bd0750csusnata        public void onChanged() {
94bb0a680c10b84b83833a59634373140f8bd0750csusnata            performLateSelection();
95bb0a680c10b84b83833a59634373140f8bd0750csusnata        }
96bb0a680c10b84b83833a59634373140f8bd0750csusnata
97bb0a680c10b84b83833a59634373140f8bd0750csusnata        public void onItemRangeInserted(int positionStart, int itemCount) {
98bb0a680c10b84b83833a59634373140f8bd0750csusnata            performLateSelection();
99bb0a680c10b84b83833a59634373140f8bd0750csusnata        }
100bb0a680c10b84b83833a59634373140f8bd0750csusnata
101bb0a680c10b84b83833a59634373140f8bd0750csusnata        void startLateSelection() {
102bb0a680c10b84b83833a59634373140f8bd0750csusnata            mIsLateSelection = true;
103bb0a680c10b84b83833a59634373140f8bd0750csusnata            mBridgeAdapter.registerAdapterDataObserver(this);
104bb0a680c10b84b83833a59634373140f8bd0750csusnata        }
105bb0a680c10b84b83833a59634373140f8bd0750csusnata
106bb0a680c10b84b83833a59634373140f8bd0750csusnata        void performLateSelection() {
107bb0a680c10b84b83833a59634373140f8bd0750csusnata            clear();
108bb0a680c10b84b83833a59634373140f8bd0750csusnata            if (mVerticalGridView != null) {
109a8a3b898da49324e83ea32c3f08776a481312166Tim Kilbourn                mVerticalGridView.setSelectedPosition(mSelectedPosition);
11055c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout            }
11155c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout        }
112bb0a680c10b84b83833a59634373140f8bd0750csusnata
113bb0a680c10b84b83833a59634373140f8bd0750csusnata        void clear() {
114bb0a680c10b84b83833a59634373140f8bd0750csusnata            if (mIsLateSelection) {
115bb0a680c10b84b83833a59634373140f8bd0750csusnata                mIsLateSelection = false;
116bb0a680c10b84b83833a59634373140f8bd0750csusnata                mBridgeAdapter.unregisterAdapterDataObserver(this);
117bb0a680c10b84b83833a59634373140f8bd0750csusnata            }
118bb0a680c10b84b83833a59634373140f8bd0750csusnata        }
119bb0a680c10b84b83833a59634373140f8bd0750csusnata    }
120bb0a680c10b84b83833a59634373140f8bd0750csusnata
121bb0a680c10b84b83833a59634373140f8bd0750csusnata    void setAdapterAndSelection() {
122bb0a680c10b84b83833a59634373140f8bd0750csusnata        mVerticalGridView.setAdapter(mBridgeAdapter);
123bb0a680c10b84b83833a59634373140f8bd0750csusnata        // We don't set the selected position unless we've data in the adapter.
124bb0a680c10b84b83833a59634373140f8bd0750csusnata        boolean lateSelection = mBridgeAdapter.getItemCount() == 0 && mSelectedPosition >= 0;
125bb0a680c10b84b83833a59634373140f8bd0750csusnata        if (lateSelection) {
126bb0a680c10b84b83833a59634373140f8bd0750csusnata            mLateSelectionObserver.startLateSelection();
127bb0a680c10b84b83833a59634373140f8bd0750csusnata        } else if (mSelectedPosition >= 0) {
128bb0a680c10b84b83833a59634373140f8bd0750csusnata            mVerticalGridView.setSelectedPosition(mSelectedPosition);
129bb0a680c10b84b83833a59634373140f8bd0750csusnata        }
13055c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout    }
13155c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout
13255c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout    @Override
13355c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout    public void onDestroyView() {
13455c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout        super.onDestroyView();
135bb0a680c10b84b83833a59634373140f8bd0750csusnata        mLateSelectionObserver.clear();
136a8a3b898da49324e83ea32c3f08776a481312166Tim Kilbourn        mVerticalGridView = null;
13755c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout    }
13855c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout
139fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak    @Override
140fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak    public void onSaveInstanceState(Bundle outState) {
141fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak        super.onSaveInstanceState(outState);
142fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak        outState.putInt(CURRENT_SELECTED_POSITION, mSelectedPosition);
143fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak    }
144fb11ded6cfa3965883e68625e0c7e14b4b4fe0b3Susnata Basak
14555c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout    /**
146cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu     * Set the presenter selector used to create and bind views.
14755c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout     */
148cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu    public final void setPresenterSelector(PresenterSelector presenterSelector) {
14955c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout        mPresenterSelector = presenterSelector;
15055c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout        updateAdapter();
15155c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout    }
15255c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout
15355c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout    /**
154cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu     * Get the presenter selector used to create and bind views.
155cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu     */
156cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu    public final PresenterSelector getPresenterSelector() {
157cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu        return mPresenterSelector;
158cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu    }
159cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu
160cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu    /**
16155c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout     * Sets the adapter for the fragment.
16255c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout     */
163cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu    public final void setAdapter(ObjectAdapter rowsAdapter) {
16455c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout        mAdapter = rowsAdapter;
16555c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout        updateAdapter();
16655c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout    }
16755c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout
16855c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout    /**
16955c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout     * Returns the list of rows.
17055c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout     */
17155c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout    public final ObjectAdapter getAdapter() {
17255c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout        return mAdapter;
17355c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout    }
17455c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout
17555c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout    /**
17655c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout     * Returns the bridge adapter.
17755c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout     */
17842752c860a26deacca04ea9ebeb00ddb4d8ce2fcDake Gu    final ItemBridgeAdapter getBridgeAdapter() {
17955c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout        return mBridgeAdapter;
18055c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout    }
18155c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout
18255c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout    /**
1833f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu     * Sets the selected row position with smooth animation.
18455c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout     */
185025aa57d4fdd4e79289303c7dc54169311728f7bCraig Stout    public void setSelectedPosition(int position) {
1863f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu        setSelectedPosition(position, true);
1873f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu    }
1883f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu
1893f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu    /**
1900d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu     * Gets position of currently selected row.
1910d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu     * @return Position of currently selected row.
1920d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu     */
1932f1bd591e01fe93f605844d4a10cde7116315b7cDake Gu    public int getSelectedPosition() {
1940d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu        return mSelectedPosition;
1950d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu    }
1960d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu
1970d73d42df7cf4b325b8f49660e3326204915ce8fDake Gu    /**
1983f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu     * Sets the selected row position.
1993f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu     */
2003f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu    public void setSelectedPosition(int position, boolean smooth) {
2010d841b3454f896da58deb506ca22730bfd04f34fDake Gu        if (mSelectedPosition == position) {
2020d841b3454f896da58deb506ca22730bfd04f34fDake Gu            return;
2030d841b3454f896da58deb506ca22730bfd04f34fDake Gu        }
20455c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout        mSelectedPosition = position;
205a8a3b898da49324e83ea32c3f08776a481312166Tim Kilbourn        if(mVerticalGridView != null && mVerticalGridView.getAdapter() != null) {
206bb0a680c10b84b83833a59634373140f8bd0750csusnata            if (mLateSelectionObserver.mIsLateSelection) {
207bb0a680c10b84b83833a59634373140f8bd0750csusnata                return;
208bb0a680c10b84b83833a59634373140f8bd0750csusnata            }
2093f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu            if (smooth) {
2103f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu                mVerticalGridView.setSelectedPositionSmooth(position);
2113f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu            } else {
2123f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu                mVerticalGridView.setSelectedPosition(position);
2133f0f3eb255bde49549a77c0b5d252decaa2a0202Dake Gu            }
21455c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout        }
21555c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout    }
21655c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout
217a8a3b898da49324e83ea32c3f08776a481312166Tim Kilbourn    final VerticalGridView getVerticalGridView() {
218a8a3b898da49324e83ea32c3f08776a481312166Tim Kilbourn        return mVerticalGridView;
21955c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout    }
22055c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout
22142752c860a26deacca04ea9ebeb00ddb4d8ce2fcDake Gu    void updateAdapter() {
222e71207666a1a915e5a5bdf7503bd936f4d87b48bDake Gu        if (mBridgeAdapter != null) {
223e71207666a1a915e5a5bdf7503bd936f4d87b48bDake Gu            // detach observer from ObjectAdapter
224bb0a680c10b84b83833a59634373140f8bd0750csusnata            mLateSelectionObserver.clear();
225e71207666a1a915e5a5bdf7503bd936f4d87b48bDake Gu            mBridgeAdapter.clear();
226e71207666a1a915e5a5bdf7503bd936f4d87b48bDake Gu            mBridgeAdapter = null;
227e71207666a1a915e5a5bdf7503bd936f4d87b48bDake Gu        }
22855c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout
22955c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout        if (mAdapter != null) {
23055c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout            // If presenter selector is null, adapter ps will be used
23155c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout            mBridgeAdapter = new ItemBridgeAdapter(mAdapter, mPresenterSelector);
23255c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout        }
233a8a3b898da49324e83ea32c3f08776a481312166Tim Kilbourn        if (mVerticalGridView != null) {
234bb0a680c10b84b83833a59634373140f8bd0750csusnata            setAdapterAndSelection();
23555c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout        }
23655c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout    }
23755c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout
23842752c860a26deacca04ea9ebeb00ddb4d8ce2fcDake Gu    Object getItem(Row row, int position) {
23955c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout        if (row instanceof ListRow) {
24055c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout            return ((ListRow) row).getAdapter().get(position);
24155c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout        } else {
24255c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout            return null;
24355c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout        }
24455c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout    }
2452f97594742886d045ca1ce409ebc6e6e780452f6Dake Gu
2462f5ebf3f6f7bb6a24856f389e369b247118ba119susnata    public boolean onTransitionPrepare() {
2472f97594742886d045ca1ce409ebc6e6e780452f6Dake Gu        if (mVerticalGridView != null) {
2482f97594742886d045ca1ce409ebc6e6e780452f6Dake Gu            mVerticalGridView.setAnimateChildLayout(false);
249902e68c114f86e8002516ff3f0248b722b6c5711Dake Gu            mVerticalGridView.setScrollEnabled(false);
250902e68c114f86e8002516ff3f0248b722b6c5711Dake Gu            return true;
2512f97594742886d045ca1ce409ebc6e6e780452f6Dake Gu        }
252902e68c114f86e8002516ff3f0248b722b6c5711Dake Gu        mPendingTransitionPrepare = true;
253902e68c114f86e8002516ff3f0248b722b6c5711Dake Gu        return false;
254902e68c114f86e8002516ff3f0248b722b6c5711Dake Gu    }
255902e68c114f86e8002516ff3f0248b722b6c5711Dake Gu
2562f5ebf3f6f7bb6a24856f389e369b247118ba119susnata    public void onTransitionStart() {
2574a4e0872bdf0548188e81740eb62085215e7f976Dake Gu        if (mVerticalGridView != null) {
2584a4e0872bdf0548188e81740eb62085215e7f976Dake Gu            mVerticalGridView.setPruneChild(false);
2594a4e0872bdf0548188e81740eb62085215e7f976Dake Gu            mVerticalGridView.setLayoutFrozen(true);
2604a4e0872bdf0548188e81740eb62085215e7f976Dake Gu            mVerticalGridView.setFocusSearchDisabled(true);
2614a4e0872bdf0548188e81740eb62085215e7f976Dake Gu        }
2622f97594742886d045ca1ce409ebc6e6e780452f6Dake Gu    }
2632f97594742886d045ca1ce409ebc6e6e780452f6Dake Gu
2642f5ebf3f6f7bb6a24856f389e369b247118ba119susnata    public void onTransitionEnd() {
2654a4e0872bdf0548188e81740eb62085215e7f976Dake Gu        // be careful that fragment might be destroyed before header transition ends.
2664a4e0872bdf0548188e81740eb62085215e7f976Dake Gu        if (mVerticalGridView != null) {
2674a4e0872bdf0548188e81740eb62085215e7f976Dake Gu            mVerticalGridView.setLayoutFrozen(false);
2684a4e0872bdf0548188e81740eb62085215e7f976Dake Gu            mVerticalGridView.setAnimateChildLayout(true);
2694a4e0872bdf0548188e81740eb62085215e7f976Dake Gu            mVerticalGridView.setPruneChild(true);
2704a4e0872bdf0548188e81740eb62085215e7f976Dake Gu            mVerticalGridView.setFocusSearchDisabled(false);
2714a4e0872bdf0548188e81740eb62085215e7f976Dake Gu            mVerticalGridView.setScrollEnabled(true);
2724a4e0872bdf0548188e81740eb62085215e7f976Dake Gu        }
2732f97594742886d045ca1ce409ebc6e6e780452f6Dake Gu    }
274e43e9266c4b7e4902fefb5d2a0cacca90a3d2681Dake Gu
2752f5ebf3f6f7bb6a24856f389e369b247118ba119susnata    public void setAlignment(int windowAlignOffsetTop) {
276e43e9266c4b7e4902fefb5d2a0cacca90a3d2681Dake Gu        if (mVerticalGridView != null) {
277e43e9266c4b7e4902fefb5d2a0cacca90a3d2681Dake Gu            // align the top edge of item
278e43e9266c4b7e4902fefb5d2a0cacca90a3d2681Dake Gu            mVerticalGridView.setItemAlignmentOffset(0);
279e43e9266c4b7e4902fefb5d2a0cacca90a3d2681Dake Gu            mVerticalGridView.setItemAlignmentOffsetPercent(
280e43e9266c4b7e4902fefb5d2a0cacca90a3d2681Dake Gu                    VerticalGridView.ITEM_ALIGN_OFFSET_PERCENT_DISABLED);
281e43e9266c4b7e4902fefb5d2a0cacca90a3d2681Dake Gu
282e43e9266c4b7e4902fefb5d2a0cacca90a3d2681Dake Gu            // align to a fixed position from top
2832f5ebf3f6f7bb6a24856f389e369b247118ba119susnata            mVerticalGridView.setWindowAlignmentOffset(windowAlignOffsetTop);
284e43e9266c4b7e4902fefb5d2a0cacca90a3d2681Dake Gu            mVerticalGridView.setWindowAlignmentOffsetPercent(
285e43e9266c4b7e4902fefb5d2a0cacca90a3d2681Dake Gu                    VerticalGridView.WINDOW_ALIGN_OFFSET_PERCENT_DISABLED);
286e43e9266c4b7e4902fefb5d2a0cacca90a3d2681Dake Gu            mVerticalGridView.setWindowAlignment(VerticalGridView.WINDOW_ALIGN_NO_EDGE);
287e43e9266c4b7e4902fefb5d2a0cacca90a3d2681Dake Gu        }
288e43e9266c4b7e4902fefb5d2a0cacca90a3d2681Dake Gu    }
28955c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout}
290