17ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout/*
27ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout * Copyright (C) 2014 The Android Open Source Project
37ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout *
47ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
57ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout * in compliance with the License. You may obtain a copy of the License at
67ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout *
77ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout * http://www.apache.org/licenses/LICENSE-2.0
87ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout *
97ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout * Unless required by applicable law or agreed to in writing, software distributed under the License
107ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
117ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout * or implied. See the License for the specific language governing permissions and limitations under
127ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout * the License.
137ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout */
147ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stoutpackage android.support.v17.leanback.widget;
157ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
16aa93f6777233b789feb14d95d900b158d0ac4841Craig Stoutimport android.content.Context;
177ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stoutimport android.support.v17.leanback.R;
187ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stoutimport android.util.SparseArray;
197ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stoutimport android.view.LayoutInflater;
207ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stoutimport android.view.View;
217ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stoutimport android.view.ViewGroup;
227ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stoutimport android.widget.LinearLayout;
237ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
247ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout/**
257ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout * A presenter that assumes a LinearLayout container for a series
267ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout * of control buttons backed by objects of type {@link Action}.
277ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout *
287ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout * Different layouts may be passed to the presenter constructor.
297ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout * The layout must contain a view with id control_bar.
307ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout */
317ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stoutclass ControlBarPresenter extends Presenter {
327ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
337ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    private static final int MAX_CONTROLS = 7;
347ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
357ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    /**
367ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout     * The data type expected by this presenter.
377ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout     */
387ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    static class BoundData {
397ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        /**
407ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout         * Adapter containing objects of type {@link Action}.
417ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout         */
427ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        ObjectAdapter adapter;
437ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
447ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        /**
457ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout         * The presenter to be used for the adapter objects.
467ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout         */
477ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        Presenter presenter;
487ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    }
497ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
507ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    /**
51cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout     * Listener for control selected events.
527ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout     */
53cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout    interface OnControlSelectedListener {
54cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout        void onControlSelected(Presenter.ViewHolder controlViewHolder, Object item,
55cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout                BoundData data);
56cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout    }
57cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout
58cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout    /**
59cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout     * Listener for control clicked events.
60cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout     */
61cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout    interface OnControlClickedListener {
62cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout        void onControlClicked(Presenter.ViewHolder controlViewHolder, Object item,
63cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout                BoundData data);
64cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout    }
65cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout
667ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    class ViewHolder extends Presenter.ViewHolder {
677ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        ObjectAdapter mAdapter;
68cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout        BoundData mData;
697ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        Presenter mPresenter;
70aa93f6777233b789feb14d95d900b158d0ac4841Craig Stout        ControlBar mControlBar;
716b447e693090017258eb48a51ae4119fb0f5119eCraig Stout        View mControlsContainer;
727ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        SparseArray<Presenter.ViewHolder> mViewHolders =
737ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                new SparseArray<Presenter.ViewHolder>();
747ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        ObjectAdapter.DataObserver mDataObserver;
757ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
767ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        /**
777ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout         * Constructor for the ViewHolder.
787ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout         */
797ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        ViewHolder(View rootView) {
807ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout            super(rootView);
816b447e693090017258eb48a51ae4119fb0f5119eCraig Stout            mControlsContainer = rootView.findViewById(R.id.controls_container);
82aa93f6777233b789feb14d95d900b158d0ac4841Craig Stout            mControlBar = (ControlBar) rootView.findViewById(R.id.control_bar);
837ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout            if (mControlBar == null) {
847ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                throw new IllegalStateException("Couldn't find control_bar");
857ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout            }
864cc255c1c9ce5f3a718970b6e0be2c3ae6abf9edCraig Stout            mControlBar.setOnChildFocusedListener(new ControlBar.OnChildFocusedListener() {
874cc255c1c9ce5f3a718970b6e0be2c3ae6abf9edCraig Stout                @Override
884cc255c1c9ce5f3a718970b6e0be2c3ae6abf9edCraig Stout                public void onChildFocusedListener(View child, View focused) {
89cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout                    if (mOnControlSelectedListener == null) {
904cc255c1c9ce5f3a718970b6e0be2c3ae6abf9edCraig Stout                        return;
914cc255c1c9ce5f3a718970b6e0be2c3ae6abf9edCraig Stout                    }
924cc255c1c9ce5f3a718970b6e0be2c3ae6abf9edCraig Stout                    for (int position = 0; position < mViewHolders.size(); position++) {
934cc255c1c9ce5f3a718970b6e0be2c3ae6abf9edCraig Stout                        if (mViewHolders.get(position).view == child) {
94cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout                            mOnControlSelectedListener.onControlSelected(
95cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout                                    mViewHolders.get(position),
96cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout                                    getDisplayedAdapter().get(position), mData);
974cc255c1c9ce5f3a718970b6e0be2c3ae6abf9edCraig Stout                            break;
984cc255c1c9ce5f3a718970b6e0be2c3ae6abf9edCraig Stout                        }
994cc255c1c9ce5f3a718970b6e0be2c3ae6abf9edCraig Stout                    }
1004cc255c1c9ce5f3a718970b6e0be2c3ae6abf9edCraig Stout                }
1014cc255c1c9ce5f3a718970b6e0be2c3ae6abf9edCraig Stout            });
1027ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout            mDataObserver = new ObjectAdapter.DataObserver() {
1037ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                @Override
1047ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                public void onChanged() {
105aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout                    if (mAdapter == getDisplayedAdapter()) {
106aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout                        showControls(mPresenter);
107aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout                    }
1087ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                }
1097ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                @Override
1107ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                public void onItemRangeChanged(int positionStart, int itemCount) {
111aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout                    if (mAdapter == getDisplayedAdapter()) {
112aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout                        for (int i = 0; i < itemCount; i++) {
113aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout                            bindControlToAction(positionStart + i, mPresenter);
114aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout                        }
1157ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                    }
1167ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                }
1177ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout            };
1187ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        }
1197ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
120aa93f6777233b789feb14d95d900b158d0ac4841Craig Stout        int getChildMarginFromCenter(Context context, int numControls) {
121aa93f6777233b789feb14d95d900b158d0ac4841Craig Stout            // Includes margin between icons plus two times half the icon width.
122aa93f6777233b789feb14d95d900b158d0ac4841Craig Stout            return getChildMarginDefault(context) + getControlIconWidth(context);
123aa93f6777233b789feb14d95d900b158d0ac4841Craig Stout        }
124aa93f6777233b789feb14d95d900b158d0ac4841Craig Stout
125aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout        void showControls(Presenter presenter) {
126aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout            ObjectAdapter adapter = getDisplayedAdapter();
1275dac2c723e1d50da356170a6f372dcbab1a7d83cCraig Stout            int adapterSize = adapter == null ? 0 : adapter.size();
128cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout            // Shrink the number of attached views
129cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout            View focusedView = mControlBar.getFocusedChild();
1305dac2c723e1d50da356170a6f372dcbab1a7d83cCraig Stout            if (focusedView != null && adapterSize > 0 &&
1315dac2c723e1d50da356170a6f372dcbab1a7d83cCraig Stout                    mControlBar.indexOfChild(focusedView) >= adapterSize) {
132cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout                mControlBar.getChildAt(adapter.size() - 1).requestFocus();
133cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout            }
1345dac2c723e1d50da356170a6f372dcbab1a7d83cCraig Stout            for (int i = mControlBar.getChildCount() - 1; i >= adapterSize; i--) {
135cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout                mControlBar.removeViewAt(i);
136cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout            }
1375dac2c723e1d50da356170a6f372dcbab1a7d83cCraig Stout            for (int position = 0; position < adapterSize && position < MAX_CONTROLS;
1387ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                    position++) {
1397ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                bindControlToAction(position, adapter, presenter);
1407ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout            }
141aa93f6777233b789feb14d95d900b158d0ac4841Craig Stout            mControlBar.setChildMarginFromCenter(
1425dac2c723e1d50da356170a6f372dcbab1a7d83cCraig Stout                    getChildMarginFromCenter(mControlBar.getContext(), adapterSize));
1437ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        }
1447ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
145aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout        void bindControlToAction(int position, Presenter presenter) {
146aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout            bindControlToAction(position, getDisplayedAdapter(), presenter);
147aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout        }
148aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout
149aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout        private void bindControlToAction(final int position,
150aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout                ObjectAdapter adapter, Presenter presenter) {
1517ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout            Presenter.ViewHolder vh = mViewHolders.get(position);
1527ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout            Object item = adapter.get(position);
1537ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout            if (vh == null) {
1547ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                vh = presenter.onCreateViewHolder(mControlBar);
1557ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                mViewHolders.put(position, vh);
156cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout
157cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout                final Presenter.ViewHolder itemViewHolder = vh;
1587ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                presenter.setOnClickListener(vh, new View.OnClickListener() {
1597ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                    @Override
1607ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                    public void onClick(View v) {
161aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout                        Object item = getDisplayedAdapter().get(position);
162cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout                        if (mOnControlClickedListener != null) {
163cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout                            mOnControlClickedListener.onControlClicked(itemViewHolder, item,
164cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout                                    mData);
1657ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                        }
1667ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                    }
1677ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                });
1687ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout            }
1697ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout            if (vh.view.getParent() == null) {
1707ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                mControlBar.addView(vh.view);
1717ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout            }
1727ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout            presenter.onBindViewHolder(vh, item);
1737ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        }
1747ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
175aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout        /**
176aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout         * Returns the adapter currently bound to the displayed controls.
177aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout         * May be overridden in a subclass.
178aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout         */
179aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout        ObjectAdapter getDisplayedAdapter() {
1807ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout            return mAdapter;
1817ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        }
1827ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    }
1837ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
184cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout    private OnControlClickedListener mOnControlClickedListener;
185cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout    private OnControlSelectedListener mOnControlSelectedListener;
1867ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    private int mLayoutResourceId;
187aa93f6777233b789feb14d95d900b158d0ac4841Craig Stout    private static int sChildMarginDefault;
188aa93f6777233b789feb14d95d900b158d0ac4841Craig Stout    private static int sControlIconWidth;
1897ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
1907ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    /**
1917ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout     * Constructor for a ControlBarPresenter.
1927ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout     *
1937ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout     * @param layoutResourceId The resource id of the layout for this presenter.
1947ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout     */
1957ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    public ControlBarPresenter(int layoutResourceId) {
1967ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        mLayoutResourceId = layoutResourceId;
1977ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    }
1987ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
1997ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    /**
2007ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout     * Returns the layout resource id.
2017ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout     */
2027ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    public int getLayoutResourceId() {
2037ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        return mLayoutResourceId;
2047ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    }
2057ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
2067ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    /**
207cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout     * Sets the listener for control clicked events.
2087ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout     */
209cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout    public void setOnControlClickedListener(OnControlClickedListener listener) {
210cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout        mOnControlClickedListener = listener;
2117ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    }
2127ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
2137ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    /**
214cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout     * Returns the listener for control clicked events.
2157ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout     */
216cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout    public OnControlClickedListener getOnItemViewClickedListener() {
217cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout        return mOnControlClickedListener;
2187ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    }
2197ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
2204cc255c1c9ce5f3a718970b6e0be2c3ae6abf9edCraig Stout    /**
221cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout     * Sets the listener for control selection.
2224cc255c1c9ce5f3a718970b6e0be2c3ae6abf9edCraig Stout     */
223cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout    public void setOnControlSelectedListener(OnControlSelectedListener listener) {
224cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout        mOnControlSelectedListener = listener;
2254cc255c1c9ce5f3a718970b6e0be2c3ae6abf9edCraig Stout    }
2264cc255c1c9ce5f3a718970b6e0be2c3ae6abf9edCraig Stout
2274cc255c1c9ce5f3a718970b6e0be2c3ae6abf9edCraig Stout    /**
228cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout     * Returns the listener for control selection.
2294cc255c1c9ce5f3a718970b6e0be2c3ae6abf9edCraig Stout     */
230cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout    public OnControlSelectedListener getOnItemControlListener() {
231cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout        return mOnControlSelectedListener;
2324cc255c1c9ce5f3a718970b6e0be2c3ae6abf9edCraig Stout    }
2334cc255c1c9ce5f3a718970b6e0be2c3ae6abf9edCraig Stout
2346b447e693090017258eb48a51ae4119fb0f5119eCraig Stout    public void setBackgroundColor(ViewHolder vh, int color) {
2356b447e693090017258eb48a51ae4119fb0f5119eCraig Stout        vh.mControlsContainer.setBackgroundColor(color);
2366b447e693090017258eb48a51ae4119fb0f5119eCraig Stout    }
2376b447e693090017258eb48a51ae4119fb0f5119eCraig Stout
2387ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    @Override
2397ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    public Presenter.ViewHolder onCreateViewHolder(ViewGroup parent) {
2407ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        View v = LayoutInflater.from(parent.getContext())
2417ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout            .inflate(getLayoutResourceId(), parent, false);
2427ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        return new ViewHolder(v);
2437ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    }
2447ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
2457ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    @Override
2467ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    public void onBindViewHolder(Presenter.ViewHolder holder, Object item) {
2477ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        ViewHolder vh = (ViewHolder) holder;
2487ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        BoundData data = (BoundData) item;
2497ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        if (vh.mAdapter != data.adapter) {
2507ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout            vh.mAdapter = data.adapter;
2515dac2c723e1d50da356170a6f372dcbab1a7d83cCraig Stout            if (vh.mAdapter != null) {
2525dac2c723e1d50da356170a6f372dcbab1a7d83cCraig Stout                vh.mAdapter.registerObserver(vh.mDataObserver);
2535dac2c723e1d50da356170a6f372dcbab1a7d83cCraig Stout            }
2547ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        }
2557ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        vh.mPresenter = data.presenter;
256cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout        vh.mData = data;
257aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout        vh.showControls(vh.mPresenter);
2587ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    }
2597ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
2607ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    @Override
2617ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    public void onUnbindViewHolder(Presenter.ViewHolder holder) {
2627ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        ViewHolder vh = (ViewHolder) holder;
2635dac2c723e1d50da356170a6f372dcbab1a7d83cCraig Stout        if (vh.mAdapter != null) {
2645dac2c723e1d50da356170a6f372dcbab1a7d83cCraig Stout            vh.mAdapter.unregisterObserver(vh.mDataObserver);
2655dac2c723e1d50da356170a6f372dcbab1a7d83cCraig Stout            vh.mAdapter = null;
2665dac2c723e1d50da356170a6f372dcbab1a7d83cCraig Stout        }
267cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout        vh.mData = null;
2687ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    }
269aa93f6777233b789feb14d95d900b158d0ac4841Craig Stout
270aa93f6777233b789feb14d95d900b158d0ac4841Craig Stout    int getChildMarginDefault(Context context) {
271aa93f6777233b789feb14d95d900b158d0ac4841Craig Stout        if (sChildMarginDefault == 0) {
272aa93f6777233b789feb14d95d900b158d0ac4841Craig Stout            sChildMarginDefault = context.getResources().getDimensionPixelSize(
273aa93f6777233b789feb14d95d900b158d0ac4841Craig Stout                    R.dimen.lb_playback_controls_child_margin_default);
274aa93f6777233b789feb14d95d900b158d0ac4841Craig Stout        }
275aa93f6777233b789feb14d95d900b158d0ac4841Craig Stout        return sChildMarginDefault;
276aa93f6777233b789feb14d95d900b158d0ac4841Craig Stout    }
277aa93f6777233b789feb14d95d900b158d0ac4841Craig Stout
278aa93f6777233b789feb14d95d900b158d0ac4841Craig Stout    int getControlIconWidth(Context context) {
279aa93f6777233b789feb14d95d900b158d0ac4841Craig Stout        if (sControlIconWidth == 0) {
280aa93f6777233b789feb14d95d900b158d0ac4841Craig Stout            sControlIconWidth = context.getResources().getDimensionPixelSize(
281aa93f6777233b789feb14d95d900b158d0ac4841Craig Stout                    R.dimen.lb_control_icon_width);
282aa93f6777233b789feb14d95d900b158d0ac4841Craig Stout        }
283aa93f6777233b789feb14d95d900b158d0ac4841Craig Stout        return sControlIconWidth;
284aa93f6777233b789feb14d95d900b158d0ac4841Craig Stout    }
2857ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout}
286