PlaybackOverlayFragment.java revision 2d33e3cfedc56adc2d4e5ac6279ec683d041fe21
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.app;
157ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
167709709c2c78490a21311e9950d5dca7e89a6aedCraig Stoutimport android.graphics.Color;
177709709c2c78490a21311e9950d5dca7e89a6aedCraig Stoutimport android.graphics.drawable.ColorDrawable;
18372d07bb41510d91a6a662a1906aceb0ee759481Craig Stoutimport android.animation.Animator;
19d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stoutimport android.animation.AnimatorInflater;
20d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stoutimport android.animation.TimeInterpolator;
21d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stoutimport android.animation.ValueAnimator;
226b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stoutimport android.view.animation.AccelerateInterpolator;
23d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stoutimport android.animation.ValueAnimator.AnimatorUpdateListener;
24d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stoutimport android.content.Context;
257ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stoutimport android.os.Bundle;
26372d07bb41510d91a6a662a1906aceb0ee759481Craig Stoutimport android.os.Handler;
27372d07bb41510d91a6a662a1906aceb0ee759481Craig Stoutimport android.os.Message;
28d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stoutimport android.support.v7.widget.RecyclerView;
297ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stoutimport android.support.v17.leanback.R;
30d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stoutimport android.support.v17.leanback.animation.LogAccelerateInterpolator;
31d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stoutimport android.support.v17.leanback.animation.LogDecelerateInterpolator;
326b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stoutimport android.support.v17.leanback.widget.Presenter;
33d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stoutimport android.support.v17.leanback.widget.ItemBridgeAdapter;
347ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stoutimport android.support.v17.leanback.widget.ObjectAdapter;
356dca725412977bb56b933bdec120e31909233cdbCraig Stoutimport android.support.v17.leanback.widget.ObjectAdapter.DataObserver;
367ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stoutimport android.support.v17.leanback.widget.VerticalGridView;
376b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stoutimport android.support.v17.leanback.widget.PlaybackControlsRowPresenter;
38372d07bb41510d91a6a662a1906aceb0ee759481Craig Stoutimport android.util.Log;
39372d07bb41510d91a6a662a1906aceb0ee759481Craig Stoutimport android.view.KeyEvent;
407709709c2c78490a21311e9950d5dca7e89a6aedCraig Stoutimport android.view.LayoutInflater;
41372d07bb41510d91a6a662a1906aceb0ee759481Craig Stoutimport android.view.MotionEvent;
427709709c2c78490a21311e9950d5dca7e89a6aedCraig Stoutimport android.view.View;
437709709c2c78490a21311e9950d5dca7e89a6aedCraig Stoutimport android.view.ViewGroup;
44d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stoutimport android.view.ViewGroup.MarginLayoutParams;
45372d07bb41510d91a6a662a1906aceb0ee759481Craig Stoutimport android.view.animation.Interpolator;
46372d07bb41510d91a6a662a1906aceb0ee759481Craig Stoutimport android.view.animation.LinearInterpolator;
477ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
482d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stoutimport java.util.ArrayList;
497ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
507ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout/**
517ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout * A fragment for displaying playback controls and related content.
526dca725412977bb56b933bdec120e31909233cdbCraig Stout * The {@link android.support.v17.leanback.widget.PlaybackControlsRow} is expected to be
536dca725412977bb56b933bdec120e31909233cdbCraig Stout * at position 0 in the adapter.
547ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout */
557ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stoutpublic class PlaybackOverlayFragment extends DetailsFragment {
567ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
577709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    /**
587709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout     * No background.
597709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout     */
607709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    public static final int BG_NONE = 0;
617709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout
627709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    /**
637709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout     * A dark translucent background.
647709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout     */
657709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    public static final int BG_DARK = 1;
667709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout
677709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    /**
687709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout     * A light translucent background.
697709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout     */
707709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    public static final int BG_LIGHT = 2;
717709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout
72372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    public static class OnFadeCompleteListener {
73372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        public void onFadeInComplete() {
74372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        }
75372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        public void onFadeOutComplete() {
76372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        }
77372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    }
78372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
79372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    private static final String TAG = "PlaybackOverlayFragment";
80372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    private static final boolean DEBUG = false;
81d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    private static final int ANIMATION_MULTIPLIER = 1;
82372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
83372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    private static int START_FADE_OUT = 1;
84372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
85372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    // Fading status
86372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    private static final int IDLE = 0;
87372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    private static final int IN = 1;
88372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    private static final int OUT = 2;
89372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
907ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    private int mAlignPosition;
91d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout    private int mPaddingBottom;
927709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    private View mRootView;
937709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    private int mBackgroundType = BG_DARK;
947709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    private int mBgDarkColor;
957709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    private int mBgLightColor;
96372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    private int mShowTimeMs;
976b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout    private int mMajorFadeTranslateY, mMinorFadeTranslateY;
986b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout    private int mAnimationTranslateY;
99372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    private OnFadeCompleteListener mFadeCompleteListener;
100372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    private boolean mFadingEnabled = true;
101372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    private int mFadingStatus = IDLE;
102d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    private int mBgAlpha;
103d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    private ValueAnimator mBgFadeInAnimator, mBgFadeOutAnimator;
104d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    private ValueAnimator mControlRowFadeInAnimator, mControlRowFadeOutAnimator;
1056b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout    private ValueAnimator mDescriptionFadeInAnimator, mDescriptionFadeOutAnimator;
106d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    private ValueAnimator mOtherRowFadeInAnimator, mOtherRowFadeOutAnimator;
107d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    private boolean mTranslateAnimationEnabled;
108aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout    private boolean mResetControlsToPrimaryActionsPending;
109d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    private RecyclerView.ItemAnimator mItemAnimator;
110372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
111372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    private final Animator.AnimatorListener mFadeListener =
112372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            new Animator.AnimatorListener() {
113372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        @Override
114372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        public void onAnimationStart(Animator animation) {
115d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            enableVerticalGridAnimations(false);
116372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        }
117372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        @Override
118372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        public void onAnimationRepeat(Animator animation) {
119372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        }
120372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        @Override
121372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        public void onAnimationCancel(Animator animation) {
122372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        }
123372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        @Override
124372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        public void onAnimationEnd(Animator animation) {
125d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            if (DEBUG) Log.v(TAG, "onAnimationEnd " + mBgAlpha);
126d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            if (mBgAlpha > 0) {
127d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                enableVerticalGridAnimations(true);
128372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout                startFadeTimer();
129372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout                if (mFadeCompleteListener != null) {
130372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout                    mFadeCompleteListener.onFadeInComplete();
131372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout                }
132d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            } else {
1331e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout                if (getVerticalGridView() != null) {
1341e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout                    // Reset focus to the controls row
1351e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout                    getVerticalGridView().setSelectedPosition(0);
136aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout                    resetControlsToPrimaryActions(null);
1371e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout                }
138d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                if (mFadeCompleteListener != null) {
139d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                    mFadeCompleteListener.onFadeOutComplete();
140d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                }
141372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            }
142372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            mFadingStatus = IDLE;
143372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        }
144372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    };
145372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
146372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    private final Handler mHandler = new Handler() {
147372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        @Override
148372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        public void handleMessage(Message message) {
149372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            if (message.what == START_FADE_OUT && mFadingEnabled) {
150372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout                fade(false);
151372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            }
152372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        }
153372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    };
154372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
155372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    private final VerticalGridView.OnTouchInterceptListener mOnTouchInterceptListener =
156372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            new VerticalGridView.OnTouchInterceptListener() {
157372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        public boolean onInterceptTouchEvent(MotionEvent event) {
158372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            return onInterceptInputEvent();
159372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        }
160372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    };
161372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
162372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    private final VerticalGridView.OnMotionInterceptListener mOnMotionInterceptListener =
163372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            new VerticalGridView.OnMotionInterceptListener() {
164372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        public boolean onInterceptMotionEvent(MotionEvent event) {
165372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            return onInterceptInputEvent();
166372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        }
167372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    };
168372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
169372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    private final VerticalGridView.OnKeyInterceptListener mOnKeyInterceptListener =
170372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            new VerticalGridView.OnKeyInterceptListener() {
171372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        public boolean onInterceptKeyEvent(KeyEvent event) {
172372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            return onInterceptInputEvent();
173372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        }
174372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    };
175372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
176d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    private void setBgAlpha(int alpha) {
177d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        mBgAlpha = alpha;
1781e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout        if (mRootView != null) {
1791e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout            mRootView.getBackground().setAlpha(alpha);
1801e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout        }
181d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    }
182d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
183d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    private void enableVerticalGridAnimations(boolean enable) {
184aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout        if (getVerticalGridView() != null) {
185aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout            getVerticalGridView().setAnimateChildLayout(enable);
186aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout        }
187aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout    }
188aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout
189aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout    private void resetControlsToPrimaryActions(ItemBridgeAdapter.ViewHolder vh) {
190aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout        if (vh == null && getVerticalGridView() != null) {
191aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout            vh = (ItemBridgeAdapter.ViewHolder) getVerticalGridView().findViewHolderForPosition(0);
1921e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout        }
193aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout        if (vh == null) {
194aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout            mResetControlsToPrimaryActionsPending = true;
195aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout        } else if (vh.getPresenter() instanceof PlaybackControlsRowPresenter) {
196aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout            mResetControlsToPrimaryActionsPending = false;
197aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout            ((PlaybackControlsRowPresenter) vh.getPresenter()).showPrimaryActions(
198aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout                    (PlaybackControlsRowPresenter.ViewHolder) vh.getViewHolder());
199d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        }
200d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    }
201d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
202372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    /**
203372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout     * Enables or disables view fading.  If enabled,
204372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout     * the view will be faded in when the fragment starts,
205372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout     * and will fade out after a time period.  The timeout
206372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout     * period is reset each time {@link #tickle} is called.
207372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout     *
208372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout     */
209372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    public void setFadingEnabled(boolean enabled) {
210372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        if (DEBUG) Log.v(TAG, "setFadingEnabled " + enabled);
211372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        if (enabled != mFadingEnabled) {
212372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            mFadingEnabled = enabled;
213372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            if (isResumed()) {
214372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout                if (mFadingEnabled) {
215372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout                    if (mFadingStatus == IDLE && !mHandler.hasMessages(START_FADE_OUT)) {
216372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout                        startFadeTimer();
217372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout                    }
218372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout                } else {
219372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout                    // Ensure fully opaque
220372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout                    mHandler.removeMessages(START_FADE_OUT);
221372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout                    fade(true);
222372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout                }
223372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            }
224372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        }
225372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    }
226372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
227372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    /**
228372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout     * Returns true if view fading is enabled.
229372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout     */
230372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    public boolean isFadingEnabled() {
231372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        return mFadingEnabled;
232372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    }
233372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
234372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    /**
235372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout     * Sets the listener to be called when fade in or out has completed.
236372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout     */
237372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    public void setFadeCompleteListener(OnFadeCompleteListener listener) {
238372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        mFadeCompleteListener = listener;
239372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    }
240372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
241372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    /**
242372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout     * Returns the listener to be called when fade in or out has completed.
243372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout     */
244372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    public OnFadeCompleteListener getFadeCompleteListener() {
245372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        return mFadeCompleteListener;
246372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    }
247372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
248372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    /**
249372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout     * Tickles the playback controls.  Fades in the view if it was faded out,
250372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout     * otherwise resets the fade out timer.  Tickling on input events is handled
251372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout     * by the fragment.
252372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout     */
253372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    public void tickle() {
254372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        if (DEBUG) Log.v(TAG, "tickle enabled " + mFadingEnabled + " isResumed " + isResumed());
255372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        if (!mFadingEnabled || !isResumed()) {
256372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            return;
257372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        }
258372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        if (mHandler.hasMessages(START_FADE_OUT)) {
259372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            // Restart the timer
260372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            startFadeTimer();
261372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        } else {
262372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            fade(true);
263372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        }
264372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    }
265372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
266372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    private boolean onInterceptInputEvent() {
267d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        if (DEBUG) Log.v(TAG, "onInterceptInputEvent status " + mFadingStatus);
268d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        boolean consumeEvent = (mFadingStatus == IDLE && mBgAlpha == 0);
269372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        tickle();
270372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        return consumeEvent;
271372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    }
272372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
273372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    @Override
274372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    public void onResume() {
275372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        super.onResume();
276372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        if (mFadingEnabled) {
277d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            setBgAlpha(0);
278372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            fade(true);
279372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        }
280372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        getVerticalGridView().setOnTouchInterceptListener(mOnTouchInterceptListener);
281372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        getVerticalGridView().setOnMotionInterceptListener(mOnMotionInterceptListener);
282372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        getVerticalGridView().setOnKeyInterceptListener(mOnKeyInterceptListener);
283372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    }
284372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
285372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    private void startFadeTimer() {
2861e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout        if (mHandler != null) {
2871e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout            mHandler.removeMessages(START_FADE_OUT);
2881e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout            mHandler.sendEmptyMessageDelayed(START_FADE_OUT, mShowTimeMs);
2891e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout        }
290372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    }
291372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
292d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    private static ValueAnimator loadAnimator(Context context, int resId) {
293d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        ValueAnimator animator = (ValueAnimator) AnimatorInflater.loadAnimator(context, resId);
294d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        animator.setDuration(animator.getDuration() * ANIMATION_MULTIPLIER);
295d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        return animator;
296d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    }
297d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
298d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    private void loadBgAnimator() {
299d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        AnimatorUpdateListener listener = new AnimatorUpdateListener() {
300d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            @Override
301d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            public void onAnimationUpdate(ValueAnimator arg0) {
302d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                setBgAlpha((Integer) arg0.getAnimatedValue());
303d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            }
304d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        };
305d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
306d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        mBgFadeInAnimator = loadAnimator(getActivity(), R.animator.lb_playback_bg_fade_in);
307d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        mBgFadeInAnimator.addUpdateListener(listener);
308d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        mBgFadeInAnimator.addListener(mFadeListener);
309d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
310d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        mBgFadeOutAnimator = loadAnimator(getActivity(), R.animator.lb_playback_bg_fade_out);
311d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        mBgFadeOutAnimator.addUpdateListener(listener);
312d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        mBgFadeOutAnimator.addListener(mFadeListener);
313d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    }
314d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
315d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    private TimeInterpolator mLogDecelerateInterpolator = new LogDecelerateInterpolator(100,0);
316d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    private TimeInterpolator mLogAccelerateInterpolator = new LogAccelerateInterpolator(100,0);
317d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
3182d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout    private View getControlRowView() {
3192d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        if (getVerticalGridView() == null) {
3202d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout            return null;
3212d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        }
3222d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        RecyclerView.ViewHolder vh = getVerticalGridView().findViewHolderForPosition(0);
3232d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        if (vh == null) {
3242d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout            return null;
3252d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        }
3262d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        return vh.itemView;
3272d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout    }
3282d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout
329d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    private void loadControlRowAnimator() {
3302d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        final AnimatorListener listener = new AnimatorListener() {
331d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            @Override
3322d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout            void getViews(ArrayList<View> views) {
3332d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout                View view = getControlRowView();
3342d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout                if (view != null) {
3352d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout                    views.add(view);
3361e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout                }
3372d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout            }
3382d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        };
3392d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        final AnimatorUpdateListener updateListener = new AnimatorUpdateListener() {
3402d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout            @Override
3412d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout            public void onAnimationUpdate(ValueAnimator arg0) {
3422d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout                View view = getControlRowView();
3432d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout                if (view != null) {
344d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                    final float fraction = (Float) arg0.getAnimatedValue();
345d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                    if (DEBUG) Log.v(TAG, "fraction " + fraction);
3462d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout                    view.setAlpha(fraction);
3472d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout                    view.setTranslationY((float) mAnimationTranslateY * (1f - fraction));
348d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                }
349d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            }
350d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        };
351d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
352d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        mControlRowFadeInAnimator = loadAnimator(
353d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                getActivity(), R.animator.lb_playback_controls_fade_in);
3542d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        mControlRowFadeInAnimator.addUpdateListener(updateListener);
3552d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        mControlRowFadeInAnimator.addListener(listener);
356d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        mControlRowFadeInAnimator.setInterpolator(mLogDecelerateInterpolator);
357d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
358d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        mControlRowFadeOutAnimator = loadAnimator(
359d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                getActivity(), R.animator.lb_playback_controls_fade_out);
3602d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        mControlRowFadeOutAnimator.addUpdateListener(updateListener);
3612d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        mControlRowFadeOutAnimator.addListener(listener);
362d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        mControlRowFadeOutAnimator.setInterpolator(mLogAccelerateInterpolator);
363d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    }
364d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
365d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    private void loadOtherRowAnimator() {
3662d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        final AnimatorListener listener = new AnimatorListener() {
367d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            @Override
3682d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout            void getViews(ArrayList<View> views) {
3691e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout                if (getVerticalGridView() == null) {
3701e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout                    return;
3711e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout                }
372d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                final int count = getVerticalGridView().getChildCount();
373d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                for (int i = 0; i < count; i++) {
374d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                    View view = getVerticalGridView().getChildAt(i);
3752d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout                    if (view != null) {
3762d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout                        views.add(view);
3772d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout                    }
3782d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout                }
3792d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout            }
3802d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        };
3812d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        final AnimatorUpdateListener updateListener = new AnimatorUpdateListener() {
3822d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout            @Override
3832d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout            public void onAnimationUpdate(ValueAnimator arg0) {
3842d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout                final float fraction = (Float) arg0.getAnimatedValue();
3852d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout                for (View view : listener.mViews) {
386d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                    if (getVerticalGridView().getChildPosition(view) > 0) {
387d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                        view.setAlpha(fraction);
3886b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                        view.setTranslationY((float) mAnimationTranslateY * (1f - fraction));
389d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                    }
390d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                }
391d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            }
392d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        };
393d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
394d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        mOtherRowFadeInAnimator = loadAnimator(
395d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                getActivity(), R.animator.lb_playback_controls_fade_in);
3962d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        mOtherRowFadeInAnimator.addListener(listener);
3972d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        mOtherRowFadeInAnimator.addUpdateListener(updateListener);
398d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        mOtherRowFadeInAnimator.setInterpolator(mLogDecelerateInterpolator);
399d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
400d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        mOtherRowFadeOutAnimator = loadAnimator(
401d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                getActivity(), R.animator.lb_playback_controls_fade_out);
4022d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        mOtherRowFadeOutAnimator.addListener(listener);
4032d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        mOtherRowFadeOutAnimator.addUpdateListener(updateListener);
4046b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout        mOtherRowFadeOutAnimator.setInterpolator(new AccelerateInterpolator());
4056b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout    }
4066b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout
4076b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout    private void loadDescriptionAnimator() {
4086b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout        AnimatorUpdateListener listener = new AnimatorUpdateListener() {
4096b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout            @Override
4106b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout            public void onAnimationUpdate(ValueAnimator arg0) {
4116b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                if (getVerticalGridView() == null) {
4126b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                    return;
4136b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                }
4146b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                ItemBridgeAdapter.ViewHolder adapterVh = (ItemBridgeAdapter.ViewHolder)
4156b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                        getVerticalGridView().findViewHolderForPosition(0);
4166b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                if (adapterVh != null && adapterVh.getViewHolder()
4176b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                        instanceof PlaybackControlsRowPresenter.ViewHolder) {
4186b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                    final Presenter.ViewHolder vh = ((PlaybackControlsRowPresenter.ViewHolder)
4196b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                            adapterVh.getViewHolder()).mDescriptionViewHolder;
4208f5c183ba7b9df6b5339586f51219b4d5e6305f3Craig Stout                    if (vh != null) {
4218f5c183ba7b9df6b5339586f51219b4d5e6305f3Craig Stout                        vh.view.setAlpha((Float) arg0.getAnimatedValue());
4228f5c183ba7b9df6b5339586f51219b4d5e6305f3Craig Stout                    }
4236b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                }
4246b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout            }
4256b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout        };
4266b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout
4276b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout        mDescriptionFadeInAnimator = loadAnimator(
4286b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                getActivity(), R.animator.lb_playback_description_fade_in);
4296b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout        mDescriptionFadeInAnimator.addUpdateListener(listener);
4306b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout        mDescriptionFadeInAnimator.setInterpolator(mLogDecelerateInterpolator);
4316b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout
4326b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout        mDescriptionFadeOutAnimator = loadAnimator(
4336b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                getActivity(), R.animator.lb_playback_description_fade_out);
4346b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout        mDescriptionFadeOutAnimator.addUpdateListener(listener);
435d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    }
436d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
437372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    private void fade(boolean fadeIn) {
438372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        if (DEBUG) Log.v(TAG, "fade " + fadeIn);
439372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        if (getView() == null) {
440372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            return;
441372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        }
442372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        if ((fadeIn && mFadingStatus == IN) || (!fadeIn && mFadingStatus == OUT)) {
443d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            if (DEBUG) Log.v(TAG, "requested fade in progress");
444d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            return;
445d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        }
446d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        if ((fadeIn && mBgAlpha == 255) || (!fadeIn && mBgAlpha == 0)) {
447d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            if (DEBUG) Log.v(TAG, "fade is no-op");
448372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            return;
449372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        }
450372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
4516b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout        mAnimationTranslateY = getVerticalGridView().getSelectedPosition() == 0 ?
4526b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                mMajorFadeTranslateY : mMinorFadeTranslateY;
453d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
454d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        if (mFadingStatus == IDLE) {
455d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            if (fadeIn) {
456d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                mBgFadeInAnimator.start();
457d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                mControlRowFadeInAnimator.start();
458d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                mOtherRowFadeInAnimator.start();
4596b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                mDescriptionFadeInAnimator.start();
460d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            } else {
461d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                mBgFadeOutAnimator.start();
462d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                mControlRowFadeOutAnimator.start();
463d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                mOtherRowFadeOutAnimator.start();
4646b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                mDescriptionFadeOutAnimator.start();
465d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            }
466d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        } else {
467d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            if (fadeIn) {
468d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                mBgFadeOutAnimator.reverse();
469d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                mControlRowFadeOutAnimator.reverse();
470d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                mOtherRowFadeOutAnimator.reverse();
4716b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                mDescriptionFadeOutAnimator.reverse();
472d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            } else {
473d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                mBgFadeInAnimator.reverse();
474d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                mControlRowFadeInAnimator.reverse();
475d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                mOtherRowFadeInAnimator.reverse();
4766b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                mDescriptionFadeInAnimator.reverse();
477d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            }
478d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        }
479d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
480d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        // If fading in while control row is focused, set initial translationY so
481d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        // views slide in from below.
4826b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout        if (fadeIn && mFadingStatus == IDLE) {
483d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            final int count = getVerticalGridView().getChildCount();
484d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            for (int i = 0; i < count; i++) {
4856b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                getVerticalGridView().getChildAt(i).setTranslationY(mAnimationTranslateY);
486d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            }
487d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        }
488d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
489372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        mFadingStatus = fadeIn ? IN : OUT;
490372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    }
4917ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
4927ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    /**
4937ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout     * Sets the list of rows for the fragment.
4947ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout     */
4957ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    @Override
4967ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    public void setAdapter(ObjectAdapter adapter) {
4976dca725412977bb56b933bdec120e31909233cdbCraig Stout        if (getAdapter() != null) {
4986dca725412977bb56b933bdec120e31909233cdbCraig Stout            getAdapter().unregisterObserver(mObserver);
4996dca725412977bb56b933bdec120e31909233cdbCraig Stout        }
5007ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        super.setAdapter(adapter);
5016dca725412977bb56b933bdec120e31909233cdbCraig Stout        if (adapter != null) {
5026dca725412977bb56b933bdec120e31909233cdbCraig Stout            adapter.registerObserver(mObserver);
5036dca725412977bb56b933bdec120e31909233cdbCraig Stout        }
5047ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    }
5057ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
5067ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    @Override
5077ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    void setVerticalGridViewLayout(VerticalGridView listview) {
508d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout        if (listview == null) {
5097ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout            return;
5107ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        }
511d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout        // Padding affects alignment when last row is focused
512d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout        // (last is first when there's only one row).
513d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout        setBottomPadding(listview, mPaddingBottom);
514d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout
515d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout        // Item alignment affects focused row that isn't the last.
516d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout        listview.setItemAlignmentOffset(mAlignPosition);
5177ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        listview.setItemAlignmentOffsetPercent(100);
518d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout
519d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout        // Push rows to the bottom.
5207ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        listview.setWindowAlignmentOffset(0);
5217ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        listview.setWindowAlignmentOffsetPercent(100);
5227ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        listview.setWindowAlignment(VerticalGridView.WINDOW_ALIGN_HIGH_EDGE);
5237ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    }
5247ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
525d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout    private static void setBottomPadding(View view, int padding) {
526d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout        view.setPadding(view.getPaddingLeft(), view.getPaddingTop(),
527d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout                view.getPaddingRight(), padding);
528d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout    }
529d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout
5307ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    @Override
5317ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    public void onCreate(Bundle savedInstanceState) {
5327ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        super.onCreate(savedInstanceState);
5337ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
5347ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        mAlignPosition =
535d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout                getResources().getDimensionPixelSize(R.dimen.lb_playback_controls_align_bottom);
536d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout        mPaddingBottom =
537d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout                getResources().getDimensionPixelSize(R.dimen.lb_playback_controls_padding_bottom);
5387709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout        mBgDarkColor =
5397709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout                getResources().getColor(R.color.lb_playback_controls_background_dark);
5407709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout        mBgLightColor =
5417709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout                getResources().getColor(R.color.lb_playback_controls_background_light);
542372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        mShowTimeMs =
543372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout                getResources().getInteger(R.integer.lb_playback_controls_show_time_ms);
5446b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout        mMajorFadeTranslateY =
5456b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                getResources().getDimensionPixelSize(R.dimen.lb_playback_major_fade_translate_y);
5466b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout        mMinorFadeTranslateY =
5476b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                getResources().getDimensionPixelSize(R.dimen.lb_playback_minor_fade_translate_y);
548d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
549d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        loadBgAnimator();
550d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        loadControlRowAnimator();
551d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        loadOtherRowAnimator();
5526b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout        loadDescriptionAnimator();
5537709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    }
5547709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout
5557709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    /**
5567709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout     * Sets the background type.
5577709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout     *
5587709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout     * @param type One of BG_LIGHT, BG_DARK, or BG_NONE.
5597709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout     */
5607709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    public void setBackgroundType(int type) {
561372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        switch (type) {
562372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        case BG_LIGHT:
563372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        case BG_DARK:
564372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        case BG_NONE:
565372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            if (type != mBackgroundType) {
566372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout                mBackgroundType = type;
567372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout                updateBackground();
568372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            }
569372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            break;
570372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        default:
5717709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout            throw new IllegalArgumentException("Invalid background type");
5727709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout        }
5737709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    }
5747709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout
5757709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    /**
5767709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout     * Returns the background type.
5777709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout     */
5787709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    public int getBackgroundType() {
5797709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout        return mBackgroundType;
5807709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    }
5817709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout
5827709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    private void updateBackground() {
5837709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout        if (mRootView != null) {
5847709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout            int color = mBgDarkColor;
5857709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout            switch (mBackgroundType) {
5867709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout                case BG_DARK: break;
5877709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout                case BG_LIGHT: color = mBgLightColor; break;
5887709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout                case BG_NONE: color = Color.TRANSPARENT; break;
5897709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout            }
5907709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout            mRootView.setBackground(new ColorDrawable(color));
5917709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout        }
5927709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    }
5937709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout
594d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout    private void updateControlsBottomSpace(ItemBridgeAdapter.ViewHolder vh) {
595d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout        // Add extra space between rows 0 and 1
596d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout        if (vh == null && getVerticalGridView() != null) {
597d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout            vh = (ItemBridgeAdapter.ViewHolder)
598d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout                    getVerticalGridView().findViewHolderForPosition(0);
599d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout        }
600d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout        if (vh != null && vh.getPresenter() instanceof PlaybackControlsRowPresenter) {
601d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout            final int adapterSize = getAdapter() == null ? 0 : getAdapter().size();
602d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout            ((PlaybackControlsRowPresenter) vh.getPresenter()).showBottomSpace(
603d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout                    (PlaybackControlsRowPresenter.ViewHolder) vh.getViewHolder(),
604d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout                    adapterSize > 1);
605d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout        }
606d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout    }
607d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout
608d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    private final ItemBridgeAdapter.AdapterListener mAdapterListener =
609d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            new ItemBridgeAdapter.AdapterListener() {
610d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        @Override
611d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        public void onAttachedToWindow(ItemBridgeAdapter.ViewHolder vh) {
612d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            if (DEBUG) Log.v(TAG, "onAttachedToWindow " + vh.getViewHolder().view);
613d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            if ((mFadingStatus == IDLE && mBgAlpha == 0) || mFadingStatus == OUT) {
614d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                if (DEBUG) Log.v(TAG, "setting alpha to 0");
615d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                vh.getViewHolder().view.setAlpha(0);
616d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            }
617aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout            if (vh.getPosition() == 0 && mResetControlsToPrimaryActionsPending) {
618aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout                resetControlsToPrimaryActions(vh);
619aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout            }
620d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        }
621d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        @Override
622d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        public void onDetachedFromWindow(ItemBridgeAdapter.ViewHolder vh) {
623d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            if (DEBUG) Log.v(TAG, "onDetachedFromWindow " + vh.getViewHolder().view);
624d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            // Reset animation state
625d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            vh.getViewHolder().view.setAlpha(1f);
626d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            vh.getViewHolder().view.setTranslationY(0);
6276b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout            if (vh.getViewHolder() instanceof PlaybackControlsRowPresenter.ViewHolder) {
6288f5c183ba7b9df6b5339586f51219b4d5e6305f3Craig Stout                Presenter.ViewHolder descriptionVh = ((PlaybackControlsRowPresenter.ViewHolder)
6298f5c183ba7b9df6b5339586f51219b4d5e6305f3Craig Stout                        vh.getViewHolder()).mDescriptionViewHolder;
6308f5c183ba7b9df6b5339586f51219b4d5e6305f3Craig Stout                if (descriptionVh != null) {
6318f5c183ba7b9df6b5339586f51219b4d5e6305f3Craig Stout                    descriptionVh.view.setAlpha(1f);
6328f5c183ba7b9df6b5339586f51219b4d5e6305f3Craig Stout                }
6336b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout            }
634d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        }
635d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout        @Override
636d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout        public void onBind(ItemBridgeAdapter.ViewHolder vh) {
637d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout            if (vh.getPosition() == 0) {
638d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout                updateControlsBottomSpace(vh);
639d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout            }
640d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout        }
641d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    };
642d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
6437709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    @Override
6447709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    public View onCreateView(LayoutInflater inflater, ViewGroup container,
6457709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout            Bundle savedInstanceState) {
6467709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout        mRootView = super.onCreateView(inflater, container, savedInstanceState);
647d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        mBgAlpha = 255;
6487709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout        updateBackground();
649d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        getRowsFragment().setExternalAdapterListener(mAdapterListener);
6507709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout        return mRootView;
6517ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    }
6526dca725412977bb56b933bdec120e31909233cdbCraig Stout
6531e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout    @Override
6541e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout    public void onDestroyView() {
6551e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout        mRootView = null;
6561e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout        super.onDestroyView();
6571e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout    }
6581e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout
6596dca725412977bb56b933bdec120e31909233cdbCraig Stout    private final DataObserver mObserver = new DataObserver() {
6606dca725412977bb56b933bdec120e31909233cdbCraig Stout        public void onChanged() {
661d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout            updateControlsBottomSpace(null);
6626dca725412977bb56b933bdec120e31909233cdbCraig Stout        }
6636dca725412977bb56b933bdec120e31909233cdbCraig Stout    };
6642d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout
6652d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout    static abstract class AnimatorListener implements Animator.AnimatorListener {
6662d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        ArrayList<View> mViews = new ArrayList<View>();
6672d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        ArrayList<Integer> mLayerType = new ArrayList<Integer>();
6682d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout
6692d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        public void onAnimationCancel(Animator animation) {
6702d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        }
6712d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        public void onAnimationRepeat(Animator animation) {
6722d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        }
6732d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        public void onAnimationStart(Animator animation) {
6742d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout            getViews(mViews);
6752d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout            for (View view : mViews) {
6762d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout                mLayerType.add(view.getLayerType());
6772d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout                view.setLayerType(View.LAYER_TYPE_HARDWARE, null);
6782d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout            }
6792d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        }
6802d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        public void onAnimationEnd(Animator animation) {
6812d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout            for (int i = 0; i < mViews.size(); i++) {
6822d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout                mViews.get(i).setLayerType(mLayerType.get(i), null);
6832d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout            }
6842d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout            mLayerType.clear();
6852d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout            mViews.clear();
6862d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        }
6872d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        abstract void getViews(ArrayList<View> views);
6882d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout    };
6897ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout}
690