PlaybackControlsPresenter.java revision 6dca725412977bb56b933bdec120e31909233cdb
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
166dca725412977bb56b933bdec120e31909233cdbCraig Stoutimport android.animation.ValueAnimator;
176dca725412977bb56b933bdec120e31909233cdbCraig Stoutimport android.graphics.drawable.ClipDrawable;
186dca725412977bb56b933bdec120e31909233cdbCraig Stoutimport android.graphics.drawable.ColorDrawable;
196dca725412977bb56b933bdec120e31909233cdbCraig Stoutimport android.graphics.drawable.Drawable;
206dca725412977bb56b933bdec120e31909233cdbCraig Stoutimport android.graphics.drawable.LayerDrawable;
217ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stoutimport android.support.v17.leanback.R;
226dca725412977bb56b933bdec120e31909233cdbCraig Stoutimport android.view.Gravity;
237ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stoutimport android.view.LayoutInflater;
247ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stoutimport android.view.View;
257ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stoutimport android.view.ViewGroup;
266dca725412977bb56b933bdec120e31909233cdbCraig Stoutimport android.view.animation.LinearInterpolator;
277ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stoutimport android.widget.FrameLayout;
286dca725412977bb56b933bdec120e31909233cdbCraig Stoutimport android.widget.ProgressBar;
296dca725412977bb56b933bdec120e31909233cdbCraig Stoutimport android.widget.TextView;
307ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
317ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout/**
327ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout * A presenter for a control bar that supports "more actions",
337ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout * and toggling the set of controls between primary and secondary
347ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout * sets of {@link Actions}.
357ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout */
367ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stoutclass PlaybackControlsPresenter extends ControlBarPresenter {
377ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
387ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    /**
397ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout     * The data type expected by this presenter.
407ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout     */
417ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    static class BoundData extends ControlBarPresenter.BoundData {
427ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        /**
437ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout         * The adapter containing secondary actions.
447ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout         */
457ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        ObjectAdapter secondaryActionsAdapter;
467ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    }
477ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
487ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    class ViewHolder extends ControlBarPresenter.ViewHolder {
497ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        ObjectAdapter mMoreActionsAdapter;
507ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        ObjectAdapter.DataObserver mMoreActionsObserver;
516dca725412977bb56b933bdec120e31909233cdbCraig Stout        final FrameLayout mMoreActionsDock;
527ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        Presenter.ViewHolder mMoreActionsViewHolder;
537ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        boolean mMoreActionsShowing;
546dca725412977bb56b933bdec120e31909233cdbCraig Stout        final TextView mCurrentTime;
556dca725412977bb56b933bdec120e31909233cdbCraig Stout        final TextView mTotalTime;
566dca725412977bb56b933bdec120e31909233cdbCraig Stout        final ProgressBar mProgressBar;
576dca725412977bb56b933bdec120e31909233cdbCraig Stout        int mCurrentTimeInSeconds;
586dca725412977bb56b933bdec120e31909233cdbCraig Stout        StringBuilder mTotalTimeStringBuilder = new StringBuilder();
596dca725412977bb56b933bdec120e31909233cdbCraig Stout        StringBuilder mCurrentTimeStringBuilder = new StringBuilder();
607ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
617ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        ViewHolder(View rootView) {
627ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout            super(rootView);
637ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout            mMoreActionsDock = (FrameLayout) rootView.findViewById(R.id.more_actions_dock);
646dca725412977bb56b933bdec120e31909233cdbCraig Stout            mCurrentTime = (TextView) rootView.findViewById(R.id.current_time);
656dca725412977bb56b933bdec120e31909233cdbCraig Stout            mTotalTime = (TextView) rootView.findViewById(R.id.total_time);
666dca725412977bb56b933bdec120e31909233cdbCraig Stout            mProgressBar = (ProgressBar) rootView.findViewById(R.id.playback_progress);
677ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout            mMoreActionsObserver = new ObjectAdapter.DataObserver() {
687ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                @Override
697ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                public void onChanged() {
707ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                    if (mMoreActionsShowing) {
717ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                        showControls(mMoreActionsAdapter, mPresenter);
727ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                    }
737ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                }
747ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                @Override
757ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                public void onItemRangeChanged(int positionStart, int itemCount) {
767ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                    if (mMoreActionsShowing) {
777ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                        for (int i = 0; i < itemCount; i++) {
787ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                            bindControlToAction(positionStart + i,
797ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                                    mMoreActionsAdapter, mPresenter);
807ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                        }
817ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                    }
827ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                }
837ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout            };
847ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        }
857ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
867ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        void showMoreActions() {
877ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout            if (mMoreActionsViewHolder == null) {
887ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                Action action = new PlaybackControlsRow.MoreActions(mMoreActionsDock.getContext());
897ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                mMoreActionsViewHolder = mPresenter.onCreateViewHolder(mMoreActionsDock);
907ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                mPresenter.onBindViewHolder(mMoreActionsViewHolder, action);
917ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                mPresenter.setOnClickListener(mMoreActionsViewHolder, new View.OnClickListener() {
927ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                    @Override
937ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                    public void onClick(View v) {
947ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                        toggleMoreActions();
957ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                    }
967ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                });
977ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout            }
987ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout            mMoreActionsDock.addView(mMoreActionsViewHolder.view);
997ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        }
1007ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
1017ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        void toggleMoreActions() {
1027ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout            mMoreActionsShowing = !mMoreActionsShowing;
1037ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout            showControls(getAdapter(), mPresenter);
1047ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        }
1057ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
1067ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        @Override
1077ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        ObjectAdapter getAdapter() {
1087ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout            return mMoreActionsShowing ? mMoreActionsAdapter : mAdapter;
1097ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        }
1106dca725412977bb56b933bdec120e31909233cdbCraig Stout
1116dca725412977bb56b933bdec120e31909233cdbCraig Stout        void setTotalTime(int totalTimeMs) {
1126dca725412977bb56b933bdec120e31909233cdbCraig Stout            if (totalTimeMs <= 0) {
1136dca725412977bb56b933bdec120e31909233cdbCraig Stout                mTotalTime.setVisibility(View.GONE);
1146dca725412977bb56b933bdec120e31909233cdbCraig Stout                mProgressBar.setVisibility(View.GONE);
1156dca725412977bb56b933bdec120e31909233cdbCraig Stout            } else {
1166dca725412977bb56b933bdec120e31909233cdbCraig Stout                mTotalTime.setVisibility(View.VISIBLE);
1176dca725412977bb56b933bdec120e31909233cdbCraig Stout                mProgressBar.setVisibility(View.VISIBLE);
1186dca725412977bb56b933bdec120e31909233cdbCraig Stout                formatTime(totalTimeMs / 1000, mTotalTimeStringBuilder);
1196dca725412977bb56b933bdec120e31909233cdbCraig Stout                mTotalTime.setText(mTotalTimeStringBuilder.toString());
1206dca725412977bb56b933bdec120e31909233cdbCraig Stout                mProgressBar.setMax(totalTimeMs);
1216dca725412977bb56b933bdec120e31909233cdbCraig Stout            }
1226dca725412977bb56b933bdec120e31909233cdbCraig Stout        }
1236dca725412977bb56b933bdec120e31909233cdbCraig Stout
1246dca725412977bb56b933bdec120e31909233cdbCraig Stout        int getTotalTime() {
1256dca725412977bb56b933bdec120e31909233cdbCraig Stout            return mProgressBar.getMax();
1266dca725412977bb56b933bdec120e31909233cdbCraig Stout        }
1276dca725412977bb56b933bdec120e31909233cdbCraig Stout
1286dca725412977bb56b933bdec120e31909233cdbCraig Stout        void setCurrentTime(int currentTimeMs) {
1296dca725412977bb56b933bdec120e31909233cdbCraig Stout            int seconds = currentTimeMs / 1000;
1306dca725412977bb56b933bdec120e31909233cdbCraig Stout            if (seconds != mCurrentTimeInSeconds) {
1316dca725412977bb56b933bdec120e31909233cdbCraig Stout                mCurrentTimeInSeconds = seconds;
1326dca725412977bb56b933bdec120e31909233cdbCraig Stout                formatTime(mCurrentTimeInSeconds, mCurrentTimeStringBuilder);
1336dca725412977bb56b933bdec120e31909233cdbCraig Stout                mCurrentTime.setText(mCurrentTimeStringBuilder.toString());
1346dca725412977bb56b933bdec120e31909233cdbCraig Stout            }
1356dca725412977bb56b933bdec120e31909233cdbCraig Stout            mProgressBar.setProgress(currentTimeMs);
1366dca725412977bb56b933bdec120e31909233cdbCraig Stout        }
1376dca725412977bb56b933bdec120e31909233cdbCraig Stout
1386dca725412977bb56b933bdec120e31909233cdbCraig Stout        int getCurrentTime() {
1396dca725412977bb56b933bdec120e31909233cdbCraig Stout            return mProgressBar.getProgress();
1406dca725412977bb56b933bdec120e31909233cdbCraig Stout        }
1416dca725412977bb56b933bdec120e31909233cdbCraig Stout
1426dca725412977bb56b933bdec120e31909233cdbCraig Stout        void setSecondaryProgress(int progressMs) {
1436dca725412977bb56b933bdec120e31909233cdbCraig Stout            mProgressBar.setSecondaryProgress(progressMs);
1446dca725412977bb56b933bdec120e31909233cdbCraig Stout        }
1456dca725412977bb56b933bdec120e31909233cdbCraig Stout
1466dca725412977bb56b933bdec120e31909233cdbCraig Stout        int getSecondaryProgress() {
1476dca725412977bb56b933bdec120e31909233cdbCraig Stout            return mProgressBar.getSecondaryProgress();
1486dca725412977bb56b933bdec120e31909233cdbCraig Stout        }
1496dca725412977bb56b933bdec120e31909233cdbCraig Stout    }
1506dca725412977bb56b933bdec120e31909233cdbCraig Stout
1516dca725412977bb56b933bdec120e31909233cdbCraig Stout    private static void formatTime(int seconds, StringBuilder sb) {
1526dca725412977bb56b933bdec120e31909233cdbCraig Stout        int minutes = seconds / 60;
1536dca725412977bb56b933bdec120e31909233cdbCraig Stout        int hours = minutes / 60;
1546dca725412977bb56b933bdec120e31909233cdbCraig Stout        seconds -= minutes * 60;
1556dca725412977bb56b933bdec120e31909233cdbCraig Stout        minutes -= hours * 60;
1566dca725412977bb56b933bdec120e31909233cdbCraig Stout
1576dca725412977bb56b933bdec120e31909233cdbCraig Stout        sb.setLength(0);
1586dca725412977bb56b933bdec120e31909233cdbCraig Stout        if (hours > 0) {
1596dca725412977bb56b933bdec120e31909233cdbCraig Stout            sb.append(hours).append(':');
1606dca725412977bb56b933bdec120e31909233cdbCraig Stout            if (minutes < 10) {
1616dca725412977bb56b933bdec120e31909233cdbCraig Stout                sb.append('0');
1626dca725412977bb56b933bdec120e31909233cdbCraig Stout            }
1636dca725412977bb56b933bdec120e31909233cdbCraig Stout        }
1646dca725412977bb56b933bdec120e31909233cdbCraig Stout        sb.append(minutes).append(':');
1656dca725412977bb56b933bdec120e31909233cdbCraig Stout        if (seconds < 10) {
1666dca725412977bb56b933bdec120e31909233cdbCraig Stout            sb.append('0');
1676dca725412977bb56b933bdec120e31909233cdbCraig Stout        }
1686dca725412977bb56b933bdec120e31909233cdbCraig Stout        sb.append(seconds);
1697ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    }
1707ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
1717ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    private boolean mMoreActionsEnabled = true;
1727ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
1737ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    /**
1747ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout     * Constructor for a PlaybackControlsRowPresenter.
1757ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout     *
1767ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout     * @param layoutResourceId The resource id of the layout for this presenter.
1777ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout     */
1787ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    public PlaybackControlsPresenter(int layoutResourceId) {
1797ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        super(layoutResourceId);
1807ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    }
1817ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
1827ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    /**
1837ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout     * Enables the display of secondary actions.
1847ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout     * A "more actions" button will be displayed.  When "more actions" is selected,
1857ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout     * the primary actions are replaced with the secondary actions.
1867ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout     */
1877ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    public void enableSecondaryActions(boolean enable) {
1887ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        mMoreActionsEnabled = enable;
1897ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    }
1907ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
1917ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    /**
1927ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout     * Returns true if secondary actions are enabled.
1937ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout     */
1947ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    public boolean areMoreActionsEnabled() {
1957ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        return mMoreActionsEnabled;
1967ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    }
1977ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
1986dca725412977bb56b933bdec120e31909233cdbCraig Stout    public void setProgressColor(ViewHolder vh, int color) {
1996dca725412977bb56b933bdec120e31909233cdbCraig Stout        Drawable drawable = new ClipDrawable(new ColorDrawable(color),
2006dca725412977bb56b933bdec120e31909233cdbCraig Stout                Gravity.LEFT, ClipDrawable.HORIZONTAL);
2016dca725412977bb56b933bdec120e31909233cdbCraig Stout        ((LayerDrawable) vh.mProgressBar.getProgressDrawable())
2026dca725412977bb56b933bdec120e31909233cdbCraig Stout                .setDrawableByLayerId(android.R.id.progress, drawable);
2036dca725412977bb56b933bdec120e31909233cdbCraig Stout    }
2046dca725412977bb56b933bdec120e31909233cdbCraig Stout
2056dca725412977bb56b933bdec120e31909233cdbCraig Stout    public void setTotalTime(ViewHolder vh, int ms) {
2066dca725412977bb56b933bdec120e31909233cdbCraig Stout        vh.setTotalTime(ms);
2076dca725412977bb56b933bdec120e31909233cdbCraig Stout    }
2086dca725412977bb56b933bdec120e31909233cdbCraig Stout
2096dca725412977bb56b933bdec120e31909233cdbCraig Stout    public int getTotalTime(ViewHolder vh) {
2106dca725412977bb56b933bdec120e31909233cdbCraig Stout        return vh.getTotalTime();
2116dca725412977bb56b933bdec120e31909233cdbCraig Stout    }
2126dca725412977bb56b933bdec120e31909233cdbCraig Stout
2136dca725412977bb56b933bdec120e31909233cdbCraig Stout    public void setCurrentTime(ViewHolder vh, int ms) {
2146dca725412977bb56b933bdec120e31909233cdbCraig Stout        vh.setCurrentTime(ms);
2156dca725412977bb56b933bdec120e31909233cdbCraig Stout    }
2166dca725412977bb56b933bdec120e31909233cdbCraig Stout
2176dca725412977bb56b933bdec120e31909233cdbCraig Stout    public int getCurrentTime(ViewHolder vh) {
2186dca725412977bb56b933bdec120e31909233cdbCraig Stout        return vh.getCurrentTime();
2196dca725412977bb56b933bdec120e31909233cdbCraig Stout    }
2206dca725412977bb56b933bdec120e31909233cdbCraig Stout
2216dca725412977bb56b933bdec120e31909233cdbCraig Stout    public void setSecondaryProgress(ViewHolder vh, int progressMs) {
2226dca725412977bb56b933bdec120e31909233cdbCraig Stout        vh.setSecondaryProgress(progressMs);
2236dca725412977bb56b933bdec120e31909233cdbCraig Stout    }
2246dca725412977bb56b933bdec120e31909233cdbCraig Stout
2256dca725412977bb56b933bdec120e31909233cdbCraig Stout    public int getSecondaryProgress(ViewHolder vh) {
2266dca725412977bb56b933bdec120e31909233cdbCraig Stout        return vh.getSecondaryProgress();
2276dca725412977bb56b933bdec120e31909233cdbCraig Stout    }
2286dca725412977bb56b933bdec120e31909233cdbCraig Stout
2297ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    @Override
2307ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    public Presenter.ViewHolder onCreateViewHolder(ViewGroup parent) {
2317ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        View v = LayoutInflater.from(parent.getContext())
2327ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout            .inflate(getLayoutResourceId(), parent, false);
2337ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        return new ViewHolder(v);
2347ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    }
2357ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
2367ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    @Override
2377ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    public void onBindViewHolder(Presenter.ViewHolder holder, Object item) {
2387ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        super.onBindViewHolder(holder, item);
2397ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
2407ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        ViewHolder vh = (ViewHolder) holder;
2417ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        BoundData data = (BoundData) item;
2427ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        if (vh.mMoreActionsAdapter != data.secondaryActionsAdapter) {
2437ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout            vh.mMoreActionsAdapter = data.secondaryActionsAdapter;
2447ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout            vh.mMoreActionsAdapter.registerObserver(vh.mMoreActionsObserver);
2457ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        }
2467ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        if (mMoreActionsEnabled) {
2477ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout            vh.showMoreActions();
2487ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        }
2497ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    }
2507ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
2517ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    @Override
2527ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    public void onUnbindViewHolder(Presenter.ViewHolder holder) {
2537ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        super.onUnbindViewHolder(holder);
2547ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        ViewHolder vh = (ViewHolder) holder;
2557ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        vh.mMoreActionsAdapter.unregisterObserver(vh.mMoreActionsObserver);
2567ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        vh.mMoreActionsAdapter = null;
2577ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    }
2587ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout}
259