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
16372d07bb41510d91a6a662a1906aceb0ee759481Craig Stoutimport android.animation.Animator;
17d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stoutimport android.animation.AnimatorInflater;
18d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stoutimport android.animation.TimeInterpolator;
19d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stoutimport android.animation.ValueAnimator;
20d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stoutimport android.animation.ValueAnimator.AnimatorUpdateListener;
21d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stoutimport android.content.Context;
223103f63e99d47573823957f7aa34308555873221Aurimas Liutikasimport android.graphics.Color;
233103f63e99d47573823957f7aa34308555873221Aurimas Liutikasimport android.graphics.drawable.ColorDrawable;
247ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stoutimport android.os.Bundle;
25372d07bb41510d91a6a662a1906aceb0ee759481Craig Stoutimport android.os.Handler;
26372d07bb41510d91a6a662a1906aceb0ee759481Craig Stoutimport android.os.Message;
277ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stoutimport android.support.v17.leanback.R;
28d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stoutimport android.support.v17.leanback.animation.LogAccelerateInterpolator;
29d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stoutimport android.support.v17.leanback.animation.LogDecelerateInterpolator;
3095ac470f2bbea06114a64906d95c0da7d9412db0Dake Guimport android.support.v17.leanback.media.PlaybackGlueHost;
315a4d3a98d681cc9042b28a923aa5a23a6b961998Dake Guimport android.support.v17.leanback.widget.ItemAlignmentFacet;
32d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stoutimport android.support.v17.leanback.widget.ItemBridgeAdapter;
337ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stoutimport android.support.v17.leanback.widget.ObjectAdapter;
346dca725412977bb56b933bdec120e31909233cdbCraig Stoutimport android.support.v17.leanback.widget.ObjectAdapter.DataObserver;
356b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stoutimport android.support.v17.leanback.widget.PlaybackControlsRowPresenter;
365a4d3a98d681cc9042b28a923aa5a23a6b961998Dake Guimport android.support.v17.leanback.widget.PlaybackRowPresenter;
3722eaa9441bf3a521bfafb160674ff2da421eded8Dake Guimport android.support.v17.leanback.widget.Presenter;
3822eaa9441bf3a521bfafb160674ff2da421eded8Dake Guimport android.support.v17.leanback.widget.PresenterSelector;
3922eaa9441bf3a521bfafb160674ff2da421eded8Dake Guimport android.support.v17.leanback.widget.RowPresenter;
4022eaa9441bf3a521bfafb160674ff2da421eded8Dake Guimport android.support.v17.leanback.widget.VerticalGridView;
413103f63e99d47573823957f7aa34308555873221Aurimas Liutikasimport android.support.v7.widget.RecyclerView;
42372d07bb41510d91a6a662a1906aceb0ee759481Craig Stoutimport android.util.Log;
433103f63e99d47573823957f7aa34308555873221Aurimas Liutikasimport android.view.InputEvent;
44372d07bb41510d91a6a662a1906aceb0ee759481Craig Stoutimport android.view.KeyEvent;
457709709c2c78490a21311e9950d5dca7e89a6aedCraig Stoutimport android.view.LayoutInflater;
46372d07bb41510d91a6a662a1906aceb0ee759481Craig Stoutimport android.view.MotionEvent;
477709709c2c78490a21311e9950d5dca7e89a6aedCraig Stoutimport android.view.View;
487709709c2c78490a21311e9950d5dca7e89a6aedCraig Stoutimport android.view.ViewGroup;
493103f63e99d47573823957f7aa34308555873221Aurimas Liutikasimport android.view.animation.AccelerateInterpolator;
507ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
51b655650666d7bd317c41c7a5be229e3a80dd2692Dake Guimport java.lang.ref.WeakReference;
522d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stoutimport java.util.ArrayList;
537ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
547ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout/**
557ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout * A fragment for displaying playback controls and related content.
56a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * <p>
57a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * A PlaybackOverlayFragment renders the elements of its {@link ObjectAdapter} as a set
5822eaa9441bf3a521bfafb160674ff2da421eded8Dake Gu * of rows in a vertical list.  The Adapter's {@link PresenterSelector} must maintain subclasses
5922eaa9441bf3a521bfafb160674ff2da421eded8Dake Gu * of {@link RowPresenter}.
60a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * </p>
61a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * <p>
62a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * An instance of {@link android.support.v17.leanback.widget.PlaybackControlsRow} is expected to be
636dca725412977bb56b933bdec120e31909233cdbCraig Stout * at position 0 in the adapter.
64a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * </p>
65afd999aba1b74d876ea2620775ba9157e6df7102susnata * <p>
66afd999aba1b74d876ea2620775ba9157e6df7102susnata *  This class is now deprecated, please us
67afd999aba1b74d876ea2620775ba9157e6df7102susnata * </p>
68afd999aba1b74d876ea2620775ba9157e6df7102susnata * @deprecated Use {@link PlaybackFragment}.
697ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout */
70afd999aba1b74d876ea2620775ba9157e6df7102susnata@Deprecated
717ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stoutpublic class PlaybackOverlayFragment extends DetailsFragment {
727ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
737709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    /**
747709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout     * No background.
757709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout     */
767709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    public static final int BG_NONE = 0;
777709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout
787709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    /**
797709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout     * A dark translucent background.
807709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout     */
817709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    public static final int BG_DARK = 1;
827709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout
837709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    /**
847709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout     * A light translucent background.
857709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout     */
867709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    public static final int BG_LIGHT = 2;
877709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout
88a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout    /**
89a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout     * Listener allowing the application to receive notification of fade in and/or fade out
90a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout     * completion events.
91a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout     */
92372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    public static class OnFadeCompleteListener {
93372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        public void onFadeInComplete() {
94372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        }
95372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        public void onFadeOutComplete() {
96372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        }
97372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    }
98372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
9999ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas    static final String TAG = "PlaybackOverlayFragment";
10099ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas    static final boolean DEBUG = false;
101d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    private static final int ANIMATION_MULTIPLIER = 1;
102372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
10399ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas    static int START_FADE_OUT = 1;
104372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
105372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    // Fading status
10699ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas    static final int IDLE = 0;
107372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    private static final int IN = 1;
10899ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas    static final int OUT = 2;
109372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
1105a4d3a98d681cc9042b28a923aa5a23a6b961998Dake Gu    private int mOtherRowsCenterToBottom;
111d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout    private int mPaddingBottom;
1127709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    private View mRootView;
1137709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    private int mBackgroundType = BG_DARK;
1147709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    private int mBgDarkColor;
1157709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    private int mBgLightColor;
116372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    private int mShowTimeMs;
1176b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout    private int mMajorFadeTranslateY, mMinorFadeTranslateY;
11899ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas    int mAnimationTranslateY;
11999ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas    OnFadeCompleteListener mFadeCompleteListener;
120afd999aba1b74d876ea2620775ba9157e6df7102susnata    private PlaybackControlGlue.InputEventHandler mInputEventHandler;
12199ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas    boolean mFadingEnabled = true;
12299ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas    int mFadingStatus = IDLE;
12399ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas    int mBgAlpha;
124d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    private ValueAnimator mBgFadeInAnimator, mBgFadeOutAnimator;
125d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    private ValueAnimator mControlRowFadeInAnimator, mControlRowFadeOutAnimator;
1266b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout    private ValueAnimator mDescriptionFadeInAnimator, mDescriptionFadeOutAnimator;
127d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    private ValueAnimator mOtherRowFadeInAnimator, mOtherRowFadeOutAnimator;
12899ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas    boolean mResetControlsToPrimaryActionsPending;
12995ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu    PlaybackGlueHost.HostCallback mHostCallback;
130372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
131372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    private final Animator.AnimatorListener mFadeListener =
132372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            new Animator.AnimatorListener() {
133372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        @Override
134372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        public void onAnimationStart(Animator animation) {
135d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            enableVerticalGridAnimations(false);
136372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        }
137372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        @Override
138372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        public void onAnimationRepeat(Animator animation) {
139372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        }
140372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        @Override
141372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        public void onAnimationCancel(Animator animation) {
142372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        }
143372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        @Override
144372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        public void onAnimationEnd(Animator animation) {
145d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            if (DEBUG) Log.v(TAG, "onAnimationEnd " + mBgAlpha);
146d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            if (mBgAlpha > 0) {
147d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                enableVerticalGridAnimations(true);
148372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout                startFadeTimer();
149372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout                if (mFadeCompleteListener != null) {
150372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout                    mFadeCompleteListener.onFadeInComplete();
151372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout                }
152d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            } else {
153794711994b16b276a7d952303a90fd4da2288362Keyvan Amiri                VerticalGridView verticalView = getVerticalGridView();
154794711994b16b276a7d952303a90fd4da2288362Keyvan Amiri                // reset focus to the primary actions only if the selected row was the controls row
155794711994b16b276a7d952303a90fd4da2288362Keyvan Amiri                if (verticalView != null && verticalView.getSelectedPosition() == 0) {
156aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout                    resetControlsToPrimaryActions(null);
1571e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout                }
158d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                if (mFadeCompleteListener != null) {
159d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                    mFadeCompleteListener.onFadeOutComplete();
160d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                }
161372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            }
162372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            mFadingStatus = IDLE;
163372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        }
164372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    };
165372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
166b655650666d7bd317c41c7a5be229e3a80dd2692Dake Gu    static class FadeHandler extends Handler {
167372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        @Override
168372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        public void handleMessage(Message message) {
169b655650666d7bd317c41c7a5be229e3a80dd2692Dake Gu            PlaybackOverlayFragment fragment;
170b655650666d7bd317c41c7a5be229e3a80dd2692Dake Gu            if (message.what == START_FADE_OUT) {
171b655650666d7bd317c41c7a5be229e3a80dd2692Dake Gu                fragment = ((WeakReference<PlaybackOverlayFragment>) message.obj).get();
172b655650666d7bd317c41c7a5be229e3a80dd2692Dake Gu                if (fragment != null && fragment.mFadingEnabled) {
173b655650666d7bd317c41c7a5be229e3a80dd2692Dake Gu                    fragment.fade(false);
174b655650666d7bd317c41c7a5be229e3a80dd2692Dake Gu                }
175372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            }
176372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        }
177b655650666d7bd317c41c7a5be229e3a80dd2692Dake Gu    }
178b655650666d7bd317c41c7a5be229e3a80dd2692Dake Gu
179b655650666d7bd317c41c7a5be229e3a80dd2692Dake Gu    static final Handler sHandler = new FadeHandler();
180b655650666d7bd317c41c7a5be229e3a80dd2692Dake Gu
181b655650666d7bd317c41c7a5be229e3a80dd2692Dake Gu    final WeakReference<PlaybackOverlayFragment> mFragmentReference =  new WeakReference(this);
182372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
183372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    private final VerticalGridView.OnTouchInterceptListener mOnTouchInterceptListener =
184372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            new VerticalGridView.OnTouchInterceptListener() {
18515375aa6fd54b036f97f99229aefab2822c8a1c9Aurimas Liutikas        @Override
186372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        public boolean onInterceptTouchEvent(MotionEvent event) {
187cbfc318baee2fc054af4c723bfac0fd3c28a1667Craig Stout            return onInterceptInputEvent(event);
188372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        }
189372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    };
190372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
191372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    private final VerticalGridView.OnKeyInterceptListener mOnKeyInterceptListener =
192372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            new VerticalGridView.OnKeyInterceptListener() {
19315375aa6fd54b036f97f99229aefab2822c8a1c9Aurimas Liutikas        @Override
194372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        public boolean onInterceptKeyEvent(KeyEvent event) {
195cbfc318baee2fc054af4c723bfac0fd3c28a1667Craig Stout            return onInterceptInputEvent(event);
196372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        }
197372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    };
198372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
19999ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas    void setBgAlpha(int alpha) {
200d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        mBgAlpha = alpha;
2011e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout        if (mRootView != null) {
2021e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout            mRootView.getBackground().setAlpha(alpha);
2031e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout        }
204d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    }
205d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
20699ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas    void enableVerticalGridAnimations(boolean enable) {
207aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout        if (getVerticalGridView() != null) {
208aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout            getVerticalGridView().setAnimateChildLayout(enable);
209aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout        }
210aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout    }
211aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout
21299ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas    void resetControlsToPrimaryActions(ItemBridgeAdapter.ViewHolder vh) {
213aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout        if (vh == null && getVerticalGridView() != null) {
214aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout            vh = (ItemBridgeAdapter.ViewHolder) getVerticalGridView().findViewHolderForPosition(0);
2151e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout        }
216aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout        if (vh == null) {
217aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout            mResetControlsToPrimaryActionsPending = true;
218aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout        } else if (vh.getPresenter() instanceof PlaybackControlsRowPresenter) {
219aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout            mResetControlsToPrimaryActionsPending = false;
220aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout            ((PlaybackControlsRowPresenter) vh.getPresenter()).showPrimaryActions(
221aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout                    (PlaybackControlsRowPresenter.ViewHolder) vh.getViewHolder());
222d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        }
223d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    }
224d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
225372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    /**
226372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout     * Enables or disables view fading.  If enabled,
227372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout     * the view will be faded in when the fragment starts,
228372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout     * and will fade out after a time period.  The timeout
229372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout     * period is reset each time {@link #tickle} is called.
230372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout     *
231372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout     */
232372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    public void setFadingEnabled(boolean enabled) {
233372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        if (DEBUG) Log.v(TAG, "setFadingEnabled " + enabled);
234372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        if (enabled != mFadingEnabled) {
235372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            mFadingEnabled = enabled;
236f47fb1e34efd538c322f7539893272ba847cdbdcCraig Stout            if (mFadingEnabled) {
237f47fb1e34efd538c322f7539893272ba847cdbdcCraig Stout                if (isResumed() && mFadingStatus == IDLE
238b655650666d7bd317c41c7a5be229e3a80dd2692Dake Gu                        && !sHandler.hasMessages(START_FADE_OUT, mFragmentReference)) {
239f47fb1e34efd538c322f7539893272ba847cdbdcCraig Stout                    startFadeTimer();
240372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout                }
241f47fb1e34efd538c322f7539893272ba847cdbdcCraig Stout            } else {
242f47fb1e34efd538c322f7539893272ba847cdbdcCraig Stout                // Ensure fully opaque
243b655650666d7bd317c41c7a5be229e3a80dd2692Dake Gu                sHandler.removeMessages(START_FADE_OUT, mFragmentReference);
244f47fb1e34efd538c322f7539893272ba847cdbdcCraig Stout                fade(true);
245372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            }
246372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        }
247372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    }
248372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
249372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    /**
250372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout     * Returns true if view fading is enabled.
251372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout     */
252372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    public boolean isFadingEnabled() {
253372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        return mFadingEnabled;
254372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    }
255372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
256372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    /**
257372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout     * Sets the listener to be called when fade in or out has completed.
258372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout     */
259372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    public void setFadeCompleteListener(OnFadeCompleteListener listener) {
260372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        mFadeCompleteListener = listener;
261372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    }
262372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
263372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    /**
264372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout     * Returns the listener to be called when fade in or out has completed.
265372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout     */
266372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    public OnFadeCompleteListener getFadeCompleteListener() {
267372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        return mFadeCompleteListener;
268372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    }
269372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
270afd999aba1b74d876ea2620775ba9157e6df7102susnata    @Deprecated
271afd999aba1b74d876ea2620775ba9157e6df7102susnata    public interface InputEventHandler extends PlaybackControlGlue.InputEventHandler {
272afd999aba1b74d876ea2620775ba9157e6df7102susnata    }
273afd999aba1b74d876ea2620775ba9157e6df7102susnata
274372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    /**
275eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout     * Sets the input event handler.
276eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout     */
277afd999aba1b74d876ea2620775ba9157e6df7102susnata    @Deprecated
278eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout    public final void setInputEventHandler(InputEventHandler handler) {
279eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout        mInputEventHandler = handler;
280eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout    }
281eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout
282eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout    /**
283eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout     * Returns the input event handler.
284eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout     */
285afd999aba1b74d876ea2620775ba9157e6df7102susnata    @Deprecated
2862dfed05c8ab53ca7c28424c9c03b1a87b9b7ca0dCraig Stout    public final InputEventHandler getInputEventHandler() {
287afd999aba1b74d876ea2620775ba9157e6df7102susnata        return (InputEventHandler)mInputEventHandler;
288afd999aba1b74d876ea2620775ba9157e6df7102susnata    }
289afd999aba1b74d876ea2620775ba9157e6df7102susnata
290afd999aba1b74d876ea2620775ba9157e6df7102susnata    /**
291afd999aba1b74d876ea2620775ba9157e6df7102susnata     * Sets the input event handler.
292afd999aba1b74d876ea2620775ba9157e6df7102susnata     */
293afd999aba1b74d876ea2620775ba9157e6df7102susnata    public final void setEventHandler(PlaybackControlGlue.InputEventHandler handler) {
294afd999aba1b74d876ea2620775ba9157e6df7102susnata        mInputEventHandler = handler;
295afd999aba1b74d876ea2620775ba9157e6df7102susnata    }
296afd999aba1b74d876ea2620775ba9157e6df7102susnata
297afd999aba1b74d876ea2620775ba9157e6df7102susnata    /**
298afd999aba1b74d876ea2620775ba9157e6df7102susnata     * Returns the input event handler.
299afd999aba1b74d876ea2620775ba9157e6df7102susnata     */
300afd999aba1b74d876ea2620775ba9157e6df7102susnata    public final PlaybackControlGlue.InputEventHandler getEventHandler() {
301eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout        return mInputEventHandler;
302eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout    }
303eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout
304eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout    /**
305372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout     * Tickles the playback controls.  Fades in the view if it was faded out,
306372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout     * otherwise resets the fade out timer.  Tickling on input events is handled
307372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout     * by the fragment.
308372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout     */
309372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    public void tickle() {
310372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        if (DEBUG) Log.v(TAG, "tickle enabled " + mFadingEnabled + " isResumed " + isResumed());
311372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        if (!mFadingEnabled || !isResumed()) {
312372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            return;
313372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        }
314b655650666d7bd317c41c7a5be229e3a80dd2692Dake Gu        if (sHandler.hasMessages(START_FADE_OUT, mFragmentReference)) {
315372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            // Restart the timer
316372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            startFadeTimer();
317372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        } else {
318372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            fade(true);
319372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        }
320372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    }
321372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
32291e100e4450b6101a674d8a3ab15e426fc5294bcDongwon Kang    /**
32391e100e4450b6101a674d8a3ab15e426fc5294bcDongwon Kang     * Fades out the playback overlay immediately.
32491e100e4450b6101a674d8a3ab15e426fc5294bcDongwon Kang     */
32591e100e4450b6101a674d8a3ab15e426fc5294bcDongwon Kang    public void fadeOut() {
326b655650666d7bd317c41c7a5be229e3a80dd2692Dake Gu        sHandler.removeMessages(START_FADE_OUT, mFragmentReference);
32791e100e4450b6101a674d8a3ab15e426fc5294bcDongwon Kang        fade(false);
32891e100e4450b6101a674d8a3ab15e426fc5294bcDongwon Kang    }
32991e100e4450b6101a674d8a3ab15e426fc5294bcDongwon Kang
33095ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu    /**
33195ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu     * Sets the {@link PlaybackGlueHost.HostCallback}. Implementor of this interface will
33295ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu     * take appropriate actions to take action when the hosting fragment starts/stops processing.
33395ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu     */
33495ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu    void setHostCallback(PlaybackGlueHost.HostCallback hostCallback) {
33595ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu        this.mHostCallback = hostCallback;
33695ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu    }
33795ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu
33895ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu    @Override
33995ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu    public void onStop() {
34095ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu        if (mHostCallback != null) {
34195ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu            mHostCallback.onHostStop();
34295ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu        }
34395ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu        super.onStop();
34495ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu    }
34595ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu
34695ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu    @Override
34795ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu    public void onPause() {
34895ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu        if (mHostCallback != null) {
34995ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu            mHostCallback.onHostPause();
35095ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu        }
35195ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu        super.onPause();
35295ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu    }
35395ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu
35460bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout    private boolean areControlsHidden() {
35560bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout        return mFadingStatus == IDLE && mBgAlpha == 0;
356cbfc318baee2fc054af4c723bfac0fd3c28a1667Craig Stout    }
357cbfc318baee2fc054af4c723bfac0fd3c28a1667Craig Stout
35899ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas    boolean onInterceptInputEvent(InputEvent event) {
35960bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout        final boolean controlsHidden = areControlsHidden();
36060bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout        if (DEBUG) Log.v(TAG, "onInterceptInputEvent hidden " + controlsHidden + " " + event);
36160bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout        boolean consumeEvent = false;
362c92c356de1a687598a031f3452053dc6c9af9b77Craig Stout        int keyCode = KeyEvent.KEYCODE_UNKNOWN;
363c92c356de1a687598a031f3452053dc6c9af9b77Craig Stout
36460bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout        if (mInputEventHandler != null) {
36560bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout            consumeEvent = mInputEventHandler.handleInputEvent(event);
36660bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout        }
367cbfc318baee2fc054af4c723bfac0fd3c28a1667Craig Stout        if (event instanceof KeyEvent) {
368c92c356de1a687598a031f3452053dc6c9af9b77Craig Stout            keyCode = ((KeyEvent) event).getKeyCode();
369c92c356de1a687598a031f3452053dc6c9af9b77Craig Stout        }
37060bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout
37160bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout        switch (keyCode) {
37260bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout            case KeyEvent.KEYCODE_DPAD_CENTER:
37360bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout            case KeyEvent.KEYCODE_DPAD_DOWN:
37460bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout            case KeyEvent.KEYCODE_DPAD_UP:
37560bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout            case KeyEvent.KEYCODE_DPAD_LEFT:
37660bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout            case KeyEvent.KEYCODE_DPAD_RIGHT:
37760bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout                // Event may be consumed; regardless, if controls are hidden then these keys will
37860bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout                // bring up the controls.
37960bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout                if (controlsHidden) {
38060bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout                    consumeEvent = true;
38160bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout                }
382cbfc318baee2fc054af4c723bfac0fd3c28a1667Craig Stout                tickle();
38360bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout                break;
38460bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout            case KeyEvent.KEYCODE_BACK:
385c89266e21f0269aecd5df2dc2a39f6f0cf11a58eCraig Stout            case KeyEvent.KEYCODE_ESCAPE:
38660bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout                // If fading enabled and controls are not hidden, back will be consumed to fade
38760bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout                // them out (even if the key was consumed by the handler).
38860bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout                if (mFadingEnabled && !controlsHidden) {
38960bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout                    consumeEvent = true;
390b655650666d7bd317c41c7a5be229e3a80dd2692Dake Gu                    sHandler.removeMessages(START_FADE_OUT, mFragmentReference);
39160bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout                    fade(false);
39260bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout                } else if (consumeEvent) {
39360bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout                    tickle();
39460bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout                }
39560bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout                break;
39660bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout            default:
39760bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout                if (consumeEvent) {
39860bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout                    tickle();
39960bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout                }
400eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout        }
401372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        return consumeEvent;
402372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    }
403372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
404372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    @Override
405372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    public void onResume() {
406372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        super.onResume();
407372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        if (mFadingEnabled) {
408d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            setBgAlpha(0);
409372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            fade(true);
410372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        }
411372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        getVerticalGridView().setOnTouchInterceptListener(mOnTouchInterceptListener);
412372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        getVerticalGridView().setOnKeyInterceptListener(mOnKeyInterceptListener);
41395ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu        if (mHostCallback != null) {
41495ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu            mHostCallback.onHostResume();
41595ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu        }
416372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    }
417372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
41899ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas    void startFadeTimer() {
419b655650666d7bd317c41c7a5be229e3a80dd2692Dake Gu        sHandler.removeMessages(START_FADE_OUT, mFragmentReference);
420b655650666d7bd317c41c7a5be229e3a80dd2692Dake Gu        sHandler.sendMessageDelayed(sHandler.obtainMessage(START_FADE_OUT, mFragmentReference),
421b655650666d7bd317c41c7a5be229e3a80dd2692Dake Gu                mShowTimeMs);
422372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    }
423372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
424d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    private static ValueAnimator loadAnimator(Context context, int resId) {
425d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        ValueAnimator animator = (ValueAnimator) AnimatorInflater.loadAnimator(context, resId);
426d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        animator.setDuration(animator.getDuration() * ANIMATION_MULTIPLIER);
427d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        return animator;
428d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    }
429d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
430d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    private void loadBgAnimator() {
431d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        AnimatorUpdateListener listener = new AnimatorUpdateListener() {
432d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            @Override
433d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            public void onAnimationUpdate(ValueAnimator arg0) {
434d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                setBgAlpha((Integer) arg0.getAnimatedValue());
435d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            }
436d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        };
437d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
4382452cde3b8d7cbe62f6eb2fbcbcf9a02448d6891Dake Gu        Context context = FragmentUtil.getContext(this);
4392452cde3b8d7cbe62f6eb2fbcbcf9a02448d6891Dake Gu        mBgFadeInAnimator = loadAnimator(context, R.animator.lb_playback_bg_fade_in);
440d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        mBgFadeInAnimator.addUpdateListener(listener);
441d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        mBgFadeInAnimator.addListener(mFadeListener);
442d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
4432452cde3b8d7cbe62f6eb2fbcbcf9a02448d6891Dake Gu        mBgFadeOutAnimator = loadAnimator(context, R.animator.lb_playback_bg_fade_out);
444d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        mBgFadeOutAnimator.addUpdateListener(listener);
445d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        mBgFadeOutAnimator.addListener(mFadeListener);
446d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    }
447d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
448d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    private TimeInterpolator mLogDecelerateInterpolator = new LogDecelerateInterpolator(100,0);
449d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    private TimeInterpolator mLogAccelerateInterpolator = new LogAccelerateInterpolator(100,0);
450d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
45199ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas    View getControlRowView() {
4522d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        if (getVerticalGridView() == null) {
4532d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout            return null;
4542d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        }
4552d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        RecyclerView.ViewHolder vh = getVerticalGridView().findViewHolderForPosition(0);
4562d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        if (vh == null) {
4572d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout            return null;
4582d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        }
4592d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        return vh.itemView;
4602d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout    }
4612d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout
462d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    private void loadControlRowAnimator() {
4632d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        final AnimatorListener listener = new AnimatorListener() {
464d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            @Override
4652d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout            void getViews(ArrayList<View> views) {
4662d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout                View view = getControlRowView();
4672d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout                if (view != null) {
4682d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout                    views.add(view);
4691e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout                }
4702d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout            }
4712d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        };
4722d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        final AnimatorUpdateListener updateListener = new AnimatorUpdateListener() {
4732d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout            @Override
4742d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout            public void onAnimationUpdate(ValueAnimator arg0) {
4752d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout                View view = getControlRowView();
4762d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout                if (view != null) {
477d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                    final float fraction = (Float) arg0.getAnimatedValue();
478d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                    if (DEBUG) Log.v(TAG, "fraction " + fraction);
4792d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout                    view.setAlpha(fraction);
4802d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout                    view.setTranslationY((float) mAnimationTranslateY * (1f - fraction));
481d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                }
482d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            }
483d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        };
484d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
4852452cde3b8d7cbe62f6eb2fbcbcf9a02448d6891Dake Gu        Context context = FragmentUtil.getContext(this);
4862452cde3b8d7cbe62f6eb2fbcbcf9a02448d6891Dake Gu        mControlRowFadeInAnimator = loadAnimator(context, R.animator.lb_playback_controls_fade_in);
4872d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        mControlRowFadeInAnimator.addUpdateListener(updateListener);
4882d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        mControlRowFadeInAnimator.addListener(listener);
489d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        mControlRowFadeInAnimator.setInterpolator(mLogDecelerateInterpolator);
490d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
4912452cde3b8d7cbe62f6eb2fbcbcf9a02448d6891Dake Gu        mControlRowFadeOutAnimator = loadAnimator(context,
4922452cde3b8d7cbe62f6eb2fbcbcf9a02448d6891Dake Gu                R.animator.lb_playback_controls_fade_out);
4932d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        mControlRowFadeOutAnimator.addUpdateListener(updateListener);
4942d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        mControlRowFadeOutAnimator.addListener(listener);
495d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        mControlRowFadeOutAnimator.setInterpolator(mLogAccelerateInterpolator);
496d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    }
497d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
498d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    private void loadOtherRowAnimator() {
4992d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        final AnimatorListener listener = new AnimatorListener() {
500d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            @Override
5012d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout            void getViews(ArrayList<View> views) {
5021e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout                if (getVerticalGridView() == null) {
5031e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout                    return;
5041e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout                }
505d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                final int count = getVerticalGridView().getChildCount();
506d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                for (int i = 0; i < count; i++) {
507d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                    View view = getVerticalGridView().getChildAt(i);
5082d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout                    if (view != null) {
5092d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout                        views.add(view);
5102d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout                    }
5112d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout                }
5122d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout            }
5132d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        };
5142d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        final AnimatorUpdateListener updateListener = new AnimatorUpdateListener() {
5152d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout            @Override
5162d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout            public void onAnimationUpdate(ValueAnimator arg0) {
5171df1f18de496764a0c922053e601d1b6d6d3f31cCraig Stout                if (getVerticalGridView() == null) {
5181df1f18de496764a0c922053e601d1b6d6d3f31cCraig Stout                    return;
5191df1f18de496764a0c922053e601d1b6d6d3f31cCraig Stout                }
5202d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout                final float fraction = (Float) arg0.getAnimatedValue();
5212d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout                for (View view : listener.mViews) {
522d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                    if (getVerticalGridView().getChildPosition(view) > 0) {
523d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                        view.setAlpha(fraction);
5246b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                        view.setTranslationY((float) mAnimationTranslateY * (1f - fraction));
525d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                    }
526d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                }
527d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            }
528d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        };
529d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
5302452cde3b8d7cbe62f6eb2fbcbcf9a02448d6891Dake Gu        Context context = FragmentUtil.getContext(this);
5312452cde3b8d7cbe62f6eb2fbcbcf9a02448d6891Dake Gu        mOtherRowFadeInAnimator = loadAnimator(context, R.animator.lb_playback_controls_fade_in);
5322d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        mOtherRowFadeInAnimator.addListener(listener);
5332d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        mOtherRowFadeInAnimator.addUpdateListener(updateListener);
534d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        mOtherRowFadeInAnimator.setInterpolator(mLogDecelerateInterpolator);
535d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
5362452cde3b8d7cbe62f6eb2fbcbcf9a02448d6891Dake Gu        mOtherRowFadeOutAnimator = loadAnimator(context, R.animator.lb_playback_controls_fade_out);
5372d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        mOtherRowFadeOutAnimator.addListener(listener);
5382d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        mOtherRowFadeOutAnimator.addUpdateListener(updateListener);
5396b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout        mOtherRowFadeOutAnimator.setInterpolator(new AccelerateInterpolator());
5406b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout    }
5416b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout
5426b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout    private void loadDescriptionAnimator() {
5436b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout        AnimatorUpdateListener listener = new AnimatorUpdateListener() {
5446b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout            @Override
5456b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout            public void onAnimationUpdate(ValueAnimator arg0) {
5466b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                if (getVerticalGridView() == null) {
5476b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                    return;
5486b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                }
5496b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                ItemBridgeAdapter.ViewHolder adapterVh = (ItemBridgeAdapter.ViewHolder)
5506b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                        getVerticalGridView().findViewHolderForPosition(0);
5516b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                if (adapterVh != null && adapterVh.getViewHolder()
5526b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                        instanceof PlaybackControlsRowPresenter.ViewHolder) {
5536b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                    final Presenter.ViewHolder vh = ((PlaybackControlsRowPresenter.ViewHolder)
5546b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                            adapterVh.getViewHolder()).mDescriptionViewHolder;
5558f5c183ba7b9df6b5339586f51219b4d5e6305f3Craig Stout                    if (vh != null) {
5568f5c183ba7b9df6b5339586f51219b4d5e6305f3Craig Stout                        vh.view.setAlpha((Float) arg0.getAnimatedValue());
5578f5c183ba7b9df6b5339586f51219b4d5e6305f3Craig Stout                    }
5586b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                }
5596b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout            }
5606b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout        };
5616b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout
5622452cde3b8d7cbe62f6eb2fbcbcf9a02448d6891Dake Gu        Context context = FragmentUtil.getContext(this);
5632452cde3b8d7cbe62f6eb2fbcbcf9a02448d6891Dake Gu        mDescriptionFadeInAnimator = loadAnimator(context,
5642452cde3b8d7cbe62f6eb2fbcbcf9a02448d6891Dake Gu                R.animator.lb_playback_description_fade_in);
5656b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout        mDescriptionFadeInAnimator.addUpdateListener(listener);
5666b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout        mDescriptionFadeInAnimator.setInterpolator(mLogDecelerateInterpolator);
5676b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout
5682452cde3b8d7cbe62f6eb2fbcbcf9a02448d6891Dake Gu        mDescriptionFadeOutAnimator = loadAnimator(context,
5692452cde3b8d7cbe62f6eb2fbcbcf9a02448d6891Dake Gu                R.animator.lb_playback_description_fade_out);
5706b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout        mDescriptionFadeOutAnimator.addUpdateListener(listener);
571d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    }
572d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
57399ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas    void fade(boolean fadeIn) {
574372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        if (DEBUG) Log.v(TAG, "fade " + fadeIn);
575372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        if (getView() == null) {
576372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            return;
577372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        }
578372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        if ((fadeIn && mFadingStatus == IN) || (!fadeIn && mFadingStatus == OUT)) {
579d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            if (DEBUG) Log.v(TAG, "requested fade in progress");
580d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            return;
581d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        }
582d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        if ((fadeIn && mBgAlpha == 255) || (!fadeIn && mBgAlpha == 0)) {
583d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            if (DEBUG) Log.v(TAG, "fade is no-op");
584372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            return;
585372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        }
586372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout
5873103f63e99d47573823957f7aa34308555873221Aurimas Liutikas        mAnimationTranslateY = getVerticalGridView().getSelectedPosition() == 0
5883103f63e99d47573823957f7aa34308555873221Aurimas Liutikas                ? mMajorFadeTranslateY : mMinorFadeTranslateY;
589d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
590d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        if (mFadingStatus == IDLE) {
591d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            if (fadeIn) {
592d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                mBgFadeInAnimator.start();
593d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                mControlRowFadeInAnimator.start();
594d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                mOtherRowFadeInAnimator.start();
5956b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                mDescriptionFadeInAnimator.start();
596d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            } else {
597d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                mBgFadeOutAnimator.start();
598d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                mControlRowFadeOutAnimator.start();
599d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                mOtherRowFadeOutAnimator.start();
6006b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                mDescriptionFadeOutAnimator.start();
601d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            }
602d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        } else {
603d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            if (fadeIn) {
604d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                mBgFadeOutAnimator.reverse();
605d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                mControlRowFadeOutAnimator.reverse();
606d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                mOtherRowFadeOutAnimator.reverse();
6076b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                mDescriptionFadeOutAnimator.reverse();
608d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            } else {
609d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                mBgFadeInAnimator.reverse();
610d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                mControlRowFadeInAnimator.reverse();
611d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                mOtherRowFadeInAnimator.reverse();
6126b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                mDescriptionFadeInAnimator.reverse();
613d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            }
614d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        }
615d2a999bfb1a2f9ca0e27e1bfdd4731abf35ab560Dake Gu        getView().announceForAccessibility(getString(fadeIn ? R.string.lb_playback_controls_shown
616d2a999bfb1a2f9ca0e27e1bfdd4731abf35ab560Dake Gu                : R.string.lb_playback_controls_hidden));
617d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
618d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        // If fading in while control row is focused, set initial translationY so
619d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        // views slide in from below.
6206b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout        if (fadeIn && mFadingStatus == IDLE) {
621d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            final int count = getVerticalGridView().getChildCount();
622d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            for (int i = 0; i < count; i++) {
6236b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                getVerticalGridView().getChildAt(i).setTranslationY(mAnimationTranslateY);
624d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            }
625d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        }
626d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
627372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        mFadingStatus = fadeIn ? IN : OUT;
628372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout    }
6297ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
6307ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    /**
6317ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout     * Sets the list of rows for the fragment.
6327ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout     */
6337ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    @Override
6347ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    public void setAdapter(ObjectAdapter adapter) {
6356dca725412977bb56b933bdec120e31909233cdbCraig Stout        if (getAdapter() != null) {
6366dca725412977bb56b933bdec120e31909233cdbCraig Stout            getAdapter().unregisterObserver(mObserver);
6376dca725412977bb56b933bdec120e31909233cdbCraig Stout        }
6387ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        super.setAdapter(adapter);
6396dca725412977bb56b933bdec120e31909233cdbCraig Stout        if (adapter != null) {
6406dca725412977bb56b933bdec120e31909233cdbCraig Stout            adapter.registerObserver(mObserver);
6416dca725412977bb56b933bdec120e31909233cdbCraig Stout        }
6427ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    }
6437ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
6447ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    @Override
6455a4d3a98d681cc9042b28a923aa5a23a6b961998Dake Gu    protected void setupPresenter(Presenter rowPresenter) {
6465a4d3a98d681cc9042b28a923aa5a23a6b961998Dake Gu        if (rowPresenter instanceof PlaybackRowPresenter) {
6475a4d3a98d681cc9042b28a923aa5a23a6b961998Dake Gu            if (rowPresenter.getFacet(ItemAlignmentFacet.class) == null) {
6485a4d3a98d681cc9042b28a923aa5a23a6b961998Dake Gu                ItemAlignmentFacet itemAlignment = new ItemAlignmentFacet();
6495a4d3a98d681cc9042b28a923aa5a23a6b961998Dake Gu                ItemAlignmentFacet.ItemAlignmentDef def =
6505a4d3a98d681cc9042b28a923aa5a23a6b961998Dake Gu                        new ItemAlignmentFacet.ItemAlignmentDef();
6515a4d3a98d681cc9042b28a923aa5a23a6b961998Dake Gu                def.setItemAlignmentOffset(0);
6525a4d3a98d681cc9042b28a923aa5a23a6b961998Dake Gu                def.setItemAlignmentOffsetPercent(100);
6535a4d3a98d681cc9042b28a923aa5a23a6b961998Dake Gu                itemAlignment.setAlignmentDefs(new ItemAlignmentFacet.ItemAlignmentDef[]
6545a4d3a98d681cc9042b28a923aa5a23a6b961998Dake Gu                        {def});
6555a4d3a98d681cc9042b28a923aa5a23a6b961998Dake Gu                rowPresenter.setFacet(ItemAlignmentFacet.class, itemAlignment);
6565a4d3a98d681cc9042b28a923aa5a23a6b961998Dake Gu            }
6575a4d3a98d681cc9042b28a923aa5a23a6b961998Dake Gu        } else {
6585a4d3a98d681cc9042b28a923aa5a23a6b961998Dake Gu            super.setupPresenter(rowPresenter);
6595a4d3a98d681cc9042b28a923aa5a23a6b961998Dake Gu        }
6605a4d3a98d681cc9042b28a923aa5a23a6b961998Dake Gu    }
6615a4d3a98d681cc9042b28a923aa5a23a6b961998Dake Gu
6625a4d3a98d681cc9042b28a923aa5a23a6b961998Dake Gu    @Override
6637ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    void setVerticalGridViewLayout(VerticalGridView listview) {
664d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout        if (listview == null) {
6657ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout            return;
6667ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        }
667d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout
6685a4d3a98d681cc9042b28a923aa5a23a6b961998Dake Gu        // we set the base line of alignment to -paddingBottom
6695a4d3a98d681cc9042b28a923aa5a23a6b961998Dake Gu        listview.setWindowAlignmentOffset(-mPaddingBottom);
6705a4d3a98d681cc9042b28a923aa5a23a6b961998Dake Gu        listview.setWindowAlignmentOffsetPercent(
6715a4d3a98d681cc9042b28a923aa5a23a6b961998Dake Gu                VerticalGridView.WINDOW_ALIGN_OFFSET_PERCENT_DISABLED);
672d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout
6735a4d3a98d681cc9042b28a923aa5a23a6b961998Dake Gu        // align other rows that arent the last to center of screen, since our baseline is
6745a4d3a98d681cc9042b28a923aa5a23a6b961998Dake Gu        // -mPaddingBottom, we need subtract that from mOtherRowsCenterToBottom.
6755a4d3a98d681cc9042b28a923aa5a23a6b961998Dake Gu        listview.setItemAlignmentOffset(mOtherRowsCenterToBottom - mPaddingBottom);
6765a4d3a98d681cc9042b28a923aa5a23a6b961998Dake Gu        listview.setItemAlignmentOffsetPercent(50);
6777ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
6785a4d3a98d681cc9042b28a923aa5a23a6b961998Dake Gu        // Push last row to the bottom padding
6795a4d3a98d681cc9042b28a923aa5a23a6b961998Dake Gu        // Padding affects alignment when last row is focused
6805a4d3a98d681cc9042b28a923aa5a23a6b961998Dake Gu        listview.setPadding(listview.getPaddingLeft(), listview.getPaddingTop(),
6815a4d3a98d681cc9042b28a923aa5a23a6b961998Dake Gu                listview.getPaddingRight(), mPaddingBottom);
6825a4d3a98d681cc9042b28a923aa5a23a6b961998Dake Gu        listview.setWindowAlignment(VerticalGridView.WINDOW_ALIGN_HIGH_EDGE);
683d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout    }
684d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout
6857ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    @Override
6867ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    public void onCreate(Bundle savedInstanceState) {
6877ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        super.onCreate(savedInstanceState);
6887ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
6895a4d3a98d681cc9042b28a923aa5a23a6b961998Dake Gu        mOtherRowsCenterToBottom = getResources()
6905a4d3a98d681cc9042b28a923aa5a23a6b961998Dake Gu                .getDimensionPixelSize(R.dimen.lb_playback_other_rows_center_to_bottom);
691d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout        mPaddingBottom =
692d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout                getResources().getDimensionPixelSize(R.dimen.lb_playback_controls_padding_bottom);
6937709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout        mBgDarkColor =
6947709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout                getResources().getColor(R.color.lb_playback_controls_background_dark);
6957709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout        mBgLightColor =
6967709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout                getResources().getColor(R.color.lb_playback_controls_background_light);
697372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        mShowTimeMs =
698372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout                getResources().getInteger(R.integer.lb_playback_controls_show_time_ms);
6996b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout        mMajorFadeTranslateY =
7006b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                getResources().getDimensionPixelSize(R.dimen.lb_playback_major_fade_translate_y);
7016b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout        mMinorFadeTranslateY =
7026b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                getResources().getDimensionPixelSize(R.dimen.lb_playback_minor_fade_translate_y);
703d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
704d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        loadBgAnimator();
705d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        loadControlRowAnimator();
706d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        loadOtherRowAnimator();
7076b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout        loadDescriptionAnimator();
7087709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    }
7097709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout
7107709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    /**
7117709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout     * Sets the background type.
7127709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout     *
7137709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout     * @param type One of BG_LIGHT, BG_DARK, or BG_NONE.
7147709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout     */
7157709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    public void setBackgroundType(int type) {
716372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        switch (type) {
717372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        case BG_LIGHT:
718372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        case BG_DARK:
719372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        case BG_NONE:
720372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            if (type != mBackgroundType) {
721372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout                mBackgroundType = type;
722372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout                updateBackground();
723372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            }
724372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout            break;
725372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout        default:
7267709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout            throw new IllegalArgumentException("Invalid background type");
7277709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout        }
7287709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    }
7297709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout
7307709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    /**
7317709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout     * Returns the background type.
7327709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout     */
7337709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    public int getBackgroundType() {
7347709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout        return mBackgroundType;
7357709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    }
7367709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout
7377709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    private void updateBackground() {
7387709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout        if (mRootView != null) {
7397709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout            int color = mBgDarkColor;
7407709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout            switch (mBackgroundType) {
7417709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout                case BG_DARK: break;
7427709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout                case BG_LIGHT: color = mBgLightColor; break;
7437709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout                case BG_NONE: color = Color.TRANSPARENT; break;
7447709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout            }
7457709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout            mRootView.setBackground(new ColorDrawable(color));
7467709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout        }
7477709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    }
7487709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout
74999ec8b0cb375f7e5577ea3ec9f09e6ff7a95de0dAurimas Liutikas    void updateControlsBottomSpace(ItemBridgeAdapter.ViewHolder vh) {
750d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout        // Add extra space between rows 0 and 1
751d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout        if (vh == null && getVerticalGridView() != null) {
752d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout            vh = (ItemBridgeAdapter.ViewHolder)
753d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout                    getVerticalGridView().findViewHolderForPosition(0);
754d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout        }
755d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout        if (vh != null && vh.getPresenter() instanceof PlaybackControlsRowPresenter) {
756d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout            final int adapterSize = getAdapter() == null ? 0 : getAdapter().size();
757d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout            ((PlaybackControlsRowPresenter) vh.getPresenter()).showBottomSpace(
758d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout                    (PlaybackControlsRowPresenter.ViewHolder) vh.getViewHolder(),
759d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout                    adapterSize > 1);
760d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout        }
761d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout    }
762d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout
763d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    private final ItemBridgeAdapter.AdapterListener mAdapterListener =
764d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            new ItemBridgeAdapter.AdapterListener() {
765d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        @Override
766d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        public void onAttachedToWindow(ItemBridgeAdapter.ViewHolder vh) {
767d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            if (DEBUG) Log.v(TAG, "onAttachedToWindow " + vh.getViewHolder().view);
768d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            if ((mFadingStatus == IDLE && mBgAlpha == 0) || mFadingStatus == OUT) {
769d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                if (DEBUG) Log.v(TAG, "setting alpha to 0");
770d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout                vh.getViewHolder().view.setAlpha(0);
771d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            }
772aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout            if (vh.getPosition() == 0 && mResetControlsToPrimaryActionsPending) {
773aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout                resetControlsToPrimaryActions(vh);
774aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout            }
775d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        }
776d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        @Override
777d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        public void onDetachedFromWindow(ItemBridgeAdapter.ViewHolder vh) {
778d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            if (DEBUG) Log.v(TAG, "onDetachedFromWindow " + vh.getViewHolder().view);
779d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            // Reset animation state
780d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            vh.getViewHolder().view.setAlpha(1f);
781d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout            vh.getViewHolder().view.setTranslationY(0);
7826b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout            if (vh.getViewHolder() instanceof PlaybackControlsRowPresenter.ViewHolder) {
7838f5c183ba7b9df6b5339586f51219b4d5e6305f3Craig Stout                Presenter.ViewHolder descriptionVh = ((PlaybackControlsRowPresenter.ViewHolder)
7848f5c183ba7b9df6b5339586f51219b4d5e6305f3Craig Stout                        vh.getViewHolder()).mDescriptionViewHolder;
7858f5c183ba7b9df6b5339586f51219b4d5e6305f3Craig Stout                if (descriptionVh != null) {
7868f5c183ba7b9df6b5339586f51219b4d5e6305f3Craig Stout                    descriptionVh.view.setAlpha(1f);
7878f5c183ba7b9df6b5339586f51219b4d5e6305f3Craig Stout                }
7886b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout            }
789d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        }
790d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout        @Override
791d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout        public void onBind(ItemBridgeAdapter.ViewHolder vh) {
792d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout            if (vh.getPosition() == 0) {
793d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout                updateControlsBottomSpace(vh);
794d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout            }
795d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout        }
796d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout    };
797d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout
7987709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    @Override
7997709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout    public View onCreateView(LayoutInflater inflater, ViewGroup container,
8007709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout            Bundle savedInstanceState) {
8017709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout        mRootView = super.onCreateView(inflater, container, savedInstanceState);
802d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        mBgAlpha = 255;
8037709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout        updateBackground();
804d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout        getRowsFragment().setExternalAdapterListener(mAdapterListener);
8057709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout        return mRootView;
8067ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    }
8076dca725412977bb56b933bdec120e31909233cdbCraig Stout
8081e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout    @Override
8091e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout    public void onDestroyView() {
8101e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout        mRootView = null;
811d34f4eb6802453f26a0df113017bc5792fc19868Dake Gu        if (mHostCallback != null) {
812d34f4eb6802453f26a0df113017bc5792fc19868Dake Gu            mHostCallback.onHostDestroy();
813d34f4eb6802453f26a0df113017bc5792fc19868Dake Gu        }
8141e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout        super.onDestroyView();
8151e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout    }
8161e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout
817fd62284fa44d88adf06deee44f4d0114ba5dec45Dake Gu    @Override
818fd62284fa44d88adf06deee44f4d0114ba5dec45Dake Gu    public void onStart() {
819fd62284fa44d88adf06deee44f4d0114ba5dec45Dake Gu        super.onStart();
820fd62284fa44d88adf06deee44f4d0114ba5dec45Dake Gu        // Workaround problem VideoView forcing itself to focused, let controls take focus.
821fd62284fa44d88adf06deee44f4d0114ba5dec45Dake Gu        getRowsFragment().getView().requestFocus();
82295ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu        if (mHostCallback != null) {
82395ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu            mHostCallback.onHostStart();
82495ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu        }
825fd62284fa44d88adf06deee44f4d0114ba5dec45Dake Gu    }
826fd62284fa44d88adf06deee44f4d0114ba5dec45Dake Gu
8276dca725412977bb56b933bdec120e31909233cdbCraig Stout    private final DataObserver mObserver = new DataObserver() {
82815375aa6fd54b036f97f99229aefab2822c8a1c9Aurimas Liutikas        @Override
8296dca725412977bb56b933bdec120e31909233cdbCraig Stout        public void onChanged() {
830d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout            updateControlsBottomSpace(null);
8316dca725412977bb56b933bdec120e31909233cdbCraig Stout        }
8326dca725412977bb56b933bdec120e31909233cdbCraig Stout    };
8332d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout
8342d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout    static abstract class AnimatorListener implements Animator.AnimatorListener {
8352d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        ArrayList<View> mViews = new ArrayList<View>();
8362d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        ArrayList<Integer> mLayerType = new ArrayList<Integer>();
8372d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout
83815375aa6fd54b036f97f99229aefab2822c8a1c9Aurimas Liutikas        @Override
8392d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        public void onAnimationCancel(Animator animation) {
8402d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        }
84115375aa6fd54b036f97f99229aefab2822c8a1c9Aurimas Liutikas        @Override
8422d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        public void onAnimationRepeat(Animator animation) {
8432d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        }
84415375aa6fd54b036f97f99229aefab2822c8a1c9Aurimas Liutikas        @Override
8452d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        public void onAnimationStart(Animator animation) {
8462d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout            getViews(mViews);
8472d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout            for (View view : mViews) {
8482d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout                mLayerType.add(view.getLayerType());
8492d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout                view.setLayerType(View.LAYER_TYPE_HARDWARE, null);
8502d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout            }
8512d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        }
85215375aa6fd54b036f97f99229aefab2822c8a1c9Aurimas Liutikas        @Override
8532d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        public void onAnimationEnd(Animator animation) {
8542d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout            for (int i = 0; i < mViews.size(); i++) {
8552d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout                mViews.get(i).setLayerType(mLayerType.get(i), null);
8562d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout            }
8572d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout            mLayerType.clear();
8582d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout            mViews.clear();
8592d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        }
8602d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout        abstract void getViews(ArrayList<View> views);
8614fe538f2d65eefc57f618887ccb1226ec1a9741dKeyvan Amiri
8622d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout    };
8637ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout}
864