PlaybackOverlayFragment.java revision 6b2e5b5117f1b8dfafbd81b995bb423ab0297564
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;
44372d07bb41510d91a6a662a1906aceb0ee759481Craig Stoutimport android.view.animation.Interpolator;
45372d07bb41510d91a6a662a1906aceb0ee759481Craig Stoutimport android.view.animation.LinearInterpolator;
467ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
477ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
487ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout/**
497ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout * A fragment for displaying playback controls and related content.
506dca725412977bb56b933bdec120e31909233cdbCraig Stout * The {@link android.support.v17.leanback.widget.PlaybackControlsRow} is expected to be
516dca725412977bb56b933bdec120e31909233cdbCraig Stout * at position 0 in the adapter.
527ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout */
537ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stoutpublic class PlaybackOverlayFragment extends DetailsFragment {
547ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
557709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    /**
567709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout     * No background.
577709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout     */
587709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    public static final int BG_NONE = 0;
597709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout
607709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    /**
617709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout     * A dark translucent background.
627709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout     */
637709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    public static final int BG_DARK = 1;
647709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout
657709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    /**
667709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout     * A light translucent background.
677709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout     */
687709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    public static final int BG_LIGHT = 2;
697709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout
70372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    public static class OnFadeCompleteListener {
71372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        public void onFadeInComplete() {
72372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        }
73372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        public void onFadeOutComplete() {
74372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        }
75372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    }
76372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
77372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    private static final String TAG = "PlaybackOverlayFragment";
78372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    private static final boolean DEBUG = false;
79d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    private static final int ANIMATION_MULTIPLIER = 1;
80372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
81372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    private static int START_FADE_OUT = 1;
82372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
83372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    // Fading status
84372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    private static final int IDLE = 0;
85372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    private static final int IN = 1;
86372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    private static final int OUT = 2;
87372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
887ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    private int mAlignPosition;
897709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    private View mRootView;
907709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    private int mBackgroundType = BG_DARK;
917709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    private int mBgDarkColor;
927709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    private int mBgLightColor;
93372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    private int mShowTimeMs;
946b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout    private int mMajorFadeTranslateY, mMinorFadeTranslateY;
956b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout    private int mAnimationTranslateY;
96372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    private OnFadeCompleteListener mFadeCompleteListener;
97372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    private boolean mFadingEnabled = true;
98372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    private int mFadingStatus = IDLE;
99d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    private int mBgAlpha;
100d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    private ValueAnimator mBgFadeInAnimator, mBgFadeOutAnimator;
101d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    private ValueAnimator mControlRowFadeInAnimator, mControlRowFadeOutAnimator;
1026b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout    private ValueAnimator mDescriptionFadeInAnimator, mDescriptionFadeOutAnimator;
103d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    private ValueAnimator mOtherRowFadeInAnimator, mOtherRowFadeOutAnimator;
104d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    private boolean mTranslateAnimationEnabled;
105d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    private RecyclerView.ItemAnimator mItemAnimator;
106372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
107372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    private final Animator.AnimatorListener mFadeListener =
108372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            new Animator.AnimatorListener() {
109372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        @Override
110372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        public void onAnimationStart(Animator animation) {
111d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            enableVerticalGridAnimations(false);
112372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        }
113372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        @Override
114372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        public void onAnimationRepeat(Animator animation) {
115372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        }
116372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        @Override
117372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        public void onAnimationCancel(Animator animation) {
118372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        }
119372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        @Override
120372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        public void onAnimationEnd(Animator animation) {
121d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            if (DEBUG) Log.v(TAG, "onAnimationEnd " + mBgAlpha);
122d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            if (mBgAlpha > 0) {
123d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                enableVerticalGridAnimations(true);
124372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout                startFadeTimer();
125372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout                if (mFadeCompleteListener != null) {
126372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout                    mFadeCompleteListener.onFadeInComplete();
127372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout                }
128d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            } else {
1291e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout                if (getVerticalGridView() != null) {
1301e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout                    // Reset focus to the controls row
1311e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout                    getVerticalGridView().setSelectedPosition(0);
1321e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout                }
133d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                if (mFadeCompleteListener != null) {
134d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                    mFadeCompleteListener.onFadeOutComplete();
135d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                }
136372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            }
137372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            mFadingStatus = IDLE;
138372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        }
139372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    };
140372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
141372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    private final Handler mHandler = new Handler() {
142372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        @Override
143372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        public void handleMessage(Message message) {
144372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            if (message.what == START_FADE_OUT && mFadingEnabled) {
145372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout                fade(false);
146372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            }
147372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        }
148372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    };
149372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
150372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    private final VerticalGridView.OnTouchInterceptListener mOnTouchInterceptListener =
151372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            new VerticalGridView.OnTouchInterceptListener() {
152372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        public boolean onInterceptTouchEvent(MotionEvent event) {
153372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            return onInterceptInputEvent();
154372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        }
155372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    };
156372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
157372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    private final VerticalGridView.OnMotionInterceptListener mOnMotionInterceptListener =
158372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            new VerticalGridView.OnMotionInterceptListener() {
159372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        public boolean onInterceptMotionEvent(MotionEvent event) {
160372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            return onInterceptInputEvent();
161372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        }
162372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    };
163372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
164372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    private final VerticalGridView.OnKeyInterceptListener mOnKeyInterceptListener =
165372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            new VerticalGridView.OnKeyInterceptListener() {
166372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        public boolean onInterceptKeyEvent(KeyEvent event) {
167372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            return onInterceptInputEvent();
168372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        }
169372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    };
170372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
171d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    private void setBgAlpha(int alpha) {
172d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        mBgAlpha = alpha;
1731e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout        if (mRootView != null) {
1741e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout            mRootView.getBackground().setAlpha(alpha);
1751e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout        }
176d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    }
177d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
178d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    private void enableVerticalGridAnimations(boolean enable) {
1791e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout        if (getVerticalGridView() == null) {
1801e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout            return;
1811e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout        }
182d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        if (enable && mItemAnimator != null) {
183d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            getVerticalGridView().setItemAnimator(mItemAnimator);
184d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        } else if (!enable) {
185d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            mItemAnimator = getVerticalGridView().getItemAnimator();
186d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            getVerticalGridView().setItemAnimator(null);
187d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        }
188d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    }
189d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
190372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    /**
191372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout     * Enables or disables view fading.  If enabled,
192372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout     * the view will be faded in when the fragment starts,
193372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout     * and will fade out after a time period.  The timeout
194372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout     * period is reset each time {@link #tickle} is called.
195372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout     *
196372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout     */
197372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    public void setFadingEnabled(boolean enabled) {
198372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        if (DEBUG) Log.v(TAG, "setFadingEnabled " + enabled);
199372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        if (enabled != mFadingEnabled) {
200372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            mFadingEnabled = enabled;
201372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            if (isResumed()) {
202372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout                if (mFadingEnabled) {
203372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout                    if (mFadingStatus == IDLE && !mHandler.hasMessages(START_FADE_OUT)) {
204372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout                        startFadeTimer();
205372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout                    }
206372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout                } else {
207372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout                    // Ensure fully opaque
208372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout                    mHandler.removeMessages(START_FADE_OUT);
209372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout                    fade(true);
210372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout                }
211372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            }
212372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        }
213372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    }
214372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
215372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    /**
216372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout     * Returns true if view fading is enabled.
217372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout     */
218372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    public boolean isFadingEnabled() {
219372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        return mFadingEnabled;
220372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    }
221372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
222372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    /**
223372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout     * Sets the listener to be called when fade in or out has completed.
224372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout     */
225372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    public void setFadeCompleteListener(OnFadeCompleteListener listener) {
226372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        mFadeCompleteListener = listener;
227372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    }
228372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
229372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    /**
230372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout     * Returns the listener to be called when fade in or out has completed.
231372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout     */
232372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    public OnFadeCompleteListener getFadeCompleteListener() {
233372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        return mFadeCompleteListener;
234372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    }
235372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
236372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    /**
237372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout     * Tickles the playback controls.  Fades in the view if it was faded out,
238372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout     * otherwise resets the fade out timer.  Tickling on input events is handled
239372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout     * by the fragment.
240372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout     */
241372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    public void tickle() {
242372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        if (DEBUG) Log.v(TAG, "tickle enabled " + mFadingEnabled + " isResumed " + isResumed());
243372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        if (!mFadingEnabled || !isResumed()) {
244372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            return;
245372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        }
246372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        if (mHandler.hasMessages(START_FADE_OUT)) {
247372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            // Restart the timer
248372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            startFadeTimer();
249372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        } else {
250372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            fade(true);
251372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        }
252372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    }
253372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
254372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    private boolean onInterceptInputEvent() {
255d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        if (DEBUG) Log.v(TAG, "onInterceptInputEvent status " + mFadingStatus);
256d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        boolean consumeEvent = (mFadingStatus == IDLE && mBgAlpha == 0);
257372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        tickle();
258372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        return consumeEvent;
259372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    }
260372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
261372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    @Override
262372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    public void onResume() {
263372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        super.onResume();
264372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        if (mFadingEnabled) {
265d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            setBgAlpha(0);
266372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            fade(true);
267372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        }
268372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        getVerticalGridView().setOnTouchInterceptListener(mOnTouchInterceptListener);
269372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        getVerticalGridView().setOnMotionInterceptListener(mOnMotionInterceptListener);
270372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        getVerticalGridView().setOnKeyInterceptListener(mOnKeyInterceptListener);
271372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    }
272372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
273372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    private void startFadeTimer() {
2741e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout        if (mHandler != null) {
2751e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout            mHandler.removeMessages(START_FADE_OUT);
2761e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout            mHandler.sendEmptyMessageDelayed(START_FADE_OUT, mShowTimeMs);
2771e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout        }
278372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    }
279372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
280d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    private static ValueAnimator loadAnimator(Context context, int resId) {
281d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        ValueAnimator animator = (ValueAnimator) AnimatorInflater.loadAnimator(context, resId);
282d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        animator.setDuration(animator.getDuration() * ANIMATION_MULTIPLIER);
283d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        return animator;
284d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    }
285d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
286d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    private void loadBgAnimator() {
287d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        AnimatorUpdateListener listener = new AnimatorUpdateListener() {
288d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            @Override
289d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            public void onAnimationUpdate(ValueAnimator arg0) {
290d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                setBgAlpha((Integer) arg0.getAnimatedValue());
291d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            }
292d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        };
293d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
294d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        mBgFadeInAnimator = loadAnimator(getActivity(), R.animator.lb_playback_bg_fade_in);
295d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        mBgFadeInAnimator.addUpdateListener(listener);
296d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        mBgFadeInAnimator.addListener(mFadeListener);
297d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
298d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        mBgFadeOutAnimator = loadAnimator(getActivity(), R.animator.lb_playback_bg_fade_out);
299d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        mBgFadeOutAnimator.addUpdateListener(listener);
300d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        mBgFadeOutAnimator.addListener(mFadeListener);
301d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    }
302d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
303d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    private TimeInterpolator mLogDecelerateInterpolator = new LogDecelerateInterpolator(100,0);
304d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    private TimeInterpolator mLogAccelerateInterpolator = new LogAccelerateInterpolator(100,0);
305d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
306d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    private void loadControlRowAnimator() {
307d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        AnimatorUpdateListener listener = new AnimatorUpdateListener() {
308d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            @Override
309d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            public void onAnimationUpdate(ValueAnimator arg0) {
3101e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout                if (getVerticalGridView() == null) {
3111e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout                    return;
3121e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout                }
313d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                RecyclerView.ViewHolder vh = getVerticalGridView().findViewHolderForPosition(0);
314d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                if (vh != null) {
315d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                    final float fraction = (Float) arg0.getAnimatedValue();
316d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                    if (DEBUG) Log.v(TAG, "fraction " + fraction);
317d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                    vh.itemView.setAlpha(fraction);
3186b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                    vh.itemView.setTranslationY((float) mAnimationTranslateY * (1f - fraction));
319d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                }
320d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            }
321d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        };
322d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
323d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        mControlRowFadeInAnimator = loadAnimator(
324d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                getActivity(), R.animator.lb_playback_controls_fade_in);
325d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        mControlRowFadeInAnimator.addUpdateListener(listener);
326d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        mControlRowFadeInAnimator.setInterpolator(mLogDecelerateInterpolator);
327d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
328d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        mControlRowFadeOutAnimator = loadAnimator(
329d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                getActivity(), R.animator.lb_playback_controls_fade_out);
330d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        mControlRowFadeOutAnimator.addUpdateListener(listener);
331d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        mControlRowFadeOutAnimator.setInterpolator(mLogAccelerateInterpolator);
332d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    }
333d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
334d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    private void loadOtherRowAnimator() {
335d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        AnimatorUpdateListener listener = new AnimatorUpdateListener() {
336d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            @Override
337d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            public void onAnimationUpdate(ValueAnimator arg0) {
3381e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout                if (getVerticalGridView() == null) {
3391e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout                    return;
3401e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout                }
341d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                final float fraction = (Float) arg0.getAnimatedValue();
342d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                final int count = getVerticalGridView().getChildCount();
343d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                for (int i = 0; i < count; i++) {
344d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                    View view = getVerticalGridView().getChildAt(i);
345d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                    if (getVerticalGridView().getChildPosition(view) > 0) {
346d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                        view.setAlpha(fraction);
3476b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                        view.setTranslationY((float) mAnimationTranslateY * (1f - fraction));
348d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                    }
349d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                }
350d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            }
351d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        };
352d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
353d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        mOtherRowFadeInAnimator = loadAnimator(
354d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                getActivity(), R.animator.lb_playback_controls_fade_in);
355d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        mOtherRowFadeInAnimator.addUpdateListener(listener);
356d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        mOtherRowFadeInAnimator.setInterpolator(mLogDecelerateInterpolator);
357d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
358d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        mOtherRowFadeOutAnimator = loadAnimator(
359d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                getActivity(), R.animator.lb_playback_controls_fade_out);
360d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        mOtherRowFadeOutAnimator.addUpdateListener(listener);
3616b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout        mOtherRowFadeOutAnimator.setInterpolator(new AccelerateInterpolator());
3626b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout    }
3636b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout
3646b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout    private void loadDescriptionAnimator() {
3656b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout        AnimatorUpdateListener listener = new AnimatorUpdateListener() {
3666b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout            @Override
3676b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout            public void onAnimationUpdate(ValueAnimator arg0) {
3686b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                if (getVerticalGridView() == null) {
3696b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                    return;
3706b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                }
3716b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                ItemBridgeAdapter.ViewHolder adapterVh = (ItemBridgeAdapter.ViewHolder)
3726b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                        getVerticalGridView().findViewHolderForPosition(0);
3736b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                if (adapterVh != null && adapterVh.getViewHolder()
3746b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                        instanceof PlaybackControlsRowPresenter.ViewHolder) {
3756b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                    final Presenter.ViewHolder vh = ((PlaybackControlsRowPresenter.ViewHolder)
3766b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                            adapterVh.getViewHolder()).mDescriptionViewHolder;
3776b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                    vh.view.setAlpha((Float) arg0.getAnimatedValue());
3786b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                }
3796b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout            }
3806b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout        };
3816b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout
3826b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout        mDescriptionFadeInAnimator = loadAnimator(
3836b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                getActivity(), R.animator.lb_playback_description_fade_in);
3846b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout        mDescriptionFadeInAnimator.addUpdateListener(listener);
3856b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout        mDescriptionFadeInAnimator.setInterpolator(mLogDecelerateInterpolator);
3866b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout
3876b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout        mDescriptionFadeOutAnimator = loadAnimator(
3886b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                getActivity(), R.animator.lb_playback_description_fade_out);
3896b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout        mDescriptionFadeOutAnimator.addUpdateListener(listener);
390d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    }
391d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
392372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    private void fade(boolean fadeIn) {
393372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        if (DEBUG) Log.v(TAG, "fade " + fadeIn);
394372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        if (getView() == null) {
395372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            return;
396372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        }
397372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        if ((fadeIn && mFadingStatus == IN) || (!fadeIn && mFadingStatus == OUT)) {
398d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            if (DEBUG) Log.v(TAG, "requested fade in progress");
399d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            return;
400d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        }
401d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        if ((fadeIn && mBgAlpha == 255) || (!fadeIn && mBgAlpha == 0)) {
402d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            if (DEBUG) Log.v(TAG, "fade is no-op");
403372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            return;
404372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        }
405372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
4066b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout        mAnimationTranslateY = getVerticalGridView().getSelectedPosition() == 0 ?
4076b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                mMajorFadeTranslateY : mMinorFadeTranslateY;
408d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
409d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        if (mFadingStatus == IDLE) {
410d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            if (fadeIn) {
411d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                mBgFadeInAnimator.start();
412d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                mControlRowFadeInAnimator.start();
413d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                mOtherRowFadeInAnimator.start();
4146b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                mDescriptionFadeInAnimator.start();
415d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            } else {
416d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                mBgFadeOutAnimator.start();
417d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                mControlRowFadeOutAnimator.start();
418d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                mOtherRowFadeOutAnimator.start();
4196b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                mDescriptionFadeOutAnimator.start();
420d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            }
421d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        } else {
422d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            if (fadeIn) {
423d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                mBgFadeOutAnimator.reverse();
424d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                mControlRowFadeOutAnimator.reverse();
425d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                mOtherRowFadeOutAnimator.reverse();
4266b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                mDescriptionFadeOutAnimator.reverse();
427d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            } else {
428d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                mBgFadeInAnimator.reverse();
429d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                mControlRowFadeInAnimator.reverse();
430d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                mOtherRowFadeInAnimator.reverse();
4316b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                mDescriptionFadeInAnimator.reverse();
432d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            }
433d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        }
434d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
435d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        // If fading in while control row is focused, set initial translationY so
436d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        // views slide in from below.
4376b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout        if (fadeIn && mFadingStatus == IDLE) {
438d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            final int count = getVerticalGridView().getChildCount();
439d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            for (int i = 0; i < count; i++) {
4406b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                getVerticalGridView().getChildAt(i).setTranslationY(mAnimationTranslateY);
441d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            }
442d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        }
443d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
444372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        mFadingStatus = fadeIn ? IN : OUT;
445372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    }
4467ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
4477ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    /**
4487ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout     * Sets the list of rows for the fragment.
4497ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout     */
4507ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    @Override
4517ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    public void setAdapter(ObjectAdapter adapter) {
4526dca725412977bb56b933bdec120e31909233cdbCraig Stout        if (getAdapter() != null) {
4536dca725412977bb56b933bdec120e31909233cdbCraig Stout            getAdapter().unregisterObserver(mObserver);
4546dca725412977bb56b933bdec120e31909233cdbCraig Stout        }
4557ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        super.setAdapter(adapter);
4566dca725412977bb56b933bdec120e31909233cdbCraig Stout        if (adapter != null) {
4576dca725412977bb56b933bdec120e31909233cdbCraig Stout            adapter.registerObserver(mObserver);
4586dca725412977bb56b933bdec120e31909233cdbCraig Stout        }
4597ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        setVerticalGridViewLayout(getVerticalGridView());
4607ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    }
4617ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
4627ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    @Override
4637ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    void setVerticalGridViewLayout(VerticalGridView listview) {
4647ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        if (listview == null || getAdapter() == null) {
4657ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout            return;
4667ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        }
4677ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        final int alignPosition = getAdapter().size() > 1 ? mAlignPosition : 0;
4687ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        listview.setItemAlignmentOffset(alignPosition);
4697ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        listview.setItemAlignmentOffsetPercent(100);
4707ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        listview.setWindowAlignmentOffset(0);
4717ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        listview.setWindowAlignmentOffsetPercent(100);
4727ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        listview.setWindowAlignment(VerticalGridView.WINDOW_ALIGN_HIGH_EDGE);
4737ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    }
4747ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
4757ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    @Override
4767ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    public void onCreate(Bundle savedInstanceState) {
4777ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        super.onCreate(savedInstanceState);
4787ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
4797ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        mAlignPosition =
4807ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout            getResources().getDimensionPixelSize(R.dimen.lb_playback_controls_align_bottom);
4817709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout        mBgDarkColor =
4827709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout                getResources().getColor(R.color.lb_playback_controls_background_dark);
4837709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout        mBgLightColor =
4847709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout                getResources().getColor(R.color.lb_playback_controls_background_light);
485372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        mShowTimeMs =
486372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout                getResources().getInteger(R.integer.lb_playback_controls_show_time_ms);
4876b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout        mMajorFadeTranslateY =
4886b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                getResources().getDimensionPixelSize(R.dimen.lb_playback_major_fade_translate_y);
4896b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout        mMinorFadeTranslateY =
4906b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                getResources().getDimensionPixelSize(R.dimen.lb_playback_minor_fade_translate_y);
491d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
492d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        loadBgAnimator();
493d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        loadControlRowAnimator();
494d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        loadOtherRowAnimator();
4956b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout        loadDescriptionAnimator();
4967709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    }
4977709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout
4987709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    /**
4997709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout     * Sets the background type.
5007709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout     *
5017709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout     * @param type One of BG_LIGHT, BG_DARK, or BG_NONE.
5027709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout     */
5037709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    public void setBackgroundType(int type) {
504372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        switch (type) {
505372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        case BG_LIGHT:
506372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        case BG_DARK:
507372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        case BG_NONE:
508372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            if (type != mBackgroundType) {
509372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout                mBackgroundType = type;
510372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout                updateBackground();
511372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            }
512372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            break;
513372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        default:
5147709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout            throw new IllegalArgumentException("Invalid background type");
5157709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout        }
5167709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    }
5177709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout
5187709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    /**
5197709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout     * Returns the background type.
5207709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout     */
5217709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    public int getBackgroundType() {
5227709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout        return mBackgroundType;
5237709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    }
5247709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout
5257709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    private void updateBackground() {
5267709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout        if (mRootView != null) {
5277709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout            int color = mBgDarkColor;
5287709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout            switch (mBackgroundType) {
5297709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout                case BG_DARK: break;
5307709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout                case BG_LIGHT: color = mBgLightColor; break;
5317709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout                case BG_NONE: color = Color.TRANSPARENT; break;
5327709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout            }
5337709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout            mRootView.setBackground(new ColorDrawable(color));
5347709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout        }
5357709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    }
5367709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout
537d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    private final ItemBridgeAdapter.AdapterListener mAdapterListener =
538d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            new ItemBridgeAdapter.AdapterListener() {
539d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        @Override
540d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        public void onAttachedToWindow(ItemBridgeAdapter.ViewHolder vh) {
541d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            if (DEBUG) Log.v(TAG, "onAttachedToWindow " + vh.getViewHolder().view);
542d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            if ((mFadingStatus == IDLE && mBgAlpha == 0) || mFadingStatus == OUT) {
543d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                if (DEBUG) Log.v(TAG, "setting alpha to 0");
544d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                vh.getViewHolder().view.setAlpha(0);
545d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            }
546d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        }
547d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        @Override
548d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        public void onDetachedFromWindow(ItemBridgeAdapter.ViewHolder vh) {
549d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            if (DEBUG) Log.v(TAG, "onDetachedFromWindow " + vh.getViewHolder().view);
550d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            // Reset animation state
551d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            vh.getViewHolder().view.setAlpha(1f);
552d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            vh.getViewHolder().view.setTranslationY(0);
5536b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout            if (vh.getViewHolder() instanceof PlaybackControlsRowPresenter.ViewHolder) {
5546b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                ((PlaybackControlsRowPresenter.ViewHolder) vh.getViewHolder())
5556b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                        .mDescriptionViewHolder.view.setAlpha(1f);
5566b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout            }
557d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        }
558d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    };
559d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
5607709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    @Override
5617709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    public View onCreateView(LayoutInflater inflater, ViewGroup container,
5627709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout            Bundle savedInstanceState) {
5637709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout        mRootView = super.onCreateView(inflater, container, savedInstanceState);
564d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        mBgAlpha = 255;
5657709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout        updateBackground();
566d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        getRowsFragment().setExternalAdapterListener(mAdapterListener);
5677709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout        return mRootView;
5687ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    }
5696dca725412977bb56b933bdec120e31909233cdbCraig Stout
5701e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout    @Override
5711e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout    public void onDestroyView() {
5721e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout        mRootView = null;
5731e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout        super.onDestroyView();
5741e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout    }
5751e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout
5766dca725412977bb56b933bdec120e31909233cdbCraig Stout    private final DataObserver mObserver = new DataObserver() {
5776dca725412977bb56b933bdec120e31909233cdbCraig Stout        public void onChanged() {
5786dca725412977bb56b933bdec120e31909233cdbCraig Stout            setVerticalGridViewLayout(getVerticalGridView());
5796dca725412977bb56b933bdec120e31909233cdbCraig Stout        }
5806dca725412977bb56b933bdec120e31909233cdbCraig Stout    };
5817ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout}
582