PlaybackOverlayFragment.java revision 15375aa6fd54b036f97f99229aefab2822c8a1c9
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; 2260bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stoutimport android.support.v17.leanback.widget.Action; 2360bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stoutimport android.support.v17.leanback.widget.PlaybackControlsRow; 24cbfc318baee2fc054af4c723bfac0fd3c28a1667Craig Stoutimport android.view.InputEvent; 256b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stoutimport android.view.animation.AccelerateInterpolator; 26d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stoutimport android.animation.ValueAnimator.AnimatorUpdateListener; 27d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stoutimport android.content.Context; 287ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stoutimport android.os.Bundle; 29372d07bb41510d91a6a662a1906aceb0ee759481Craig Stoutimport android.os.Handler; 30372d07bb41510d91a6a662a1906aceb0ee759481Craig Stoutimport android.os.Message; 31d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stoutimport android.support.v7.widget.RecyclerView; 327ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stoutimport android.support.v17.leanback.R; 33d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stoutimport android.support.v17.leanback.animation.LogAccelerateInterpolator; 34d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stoutimport android.support.v17.leanback.animation.LogDecelerateInterpolator; 35d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stoutimport android.support.v17.leanback.widget.ItemBridgeAdapter; 367ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stoutimport android.support.v17.leanback.widget.ObjectAdapter; 376dca725412977bb56b933bdec120e31909233cdbCraig Stoutimport android.support.v17.leanback.widget.ObjectAdapter.DataObserver; 386b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stoutimport android.support.v17.leanback.widget.PlaybackControlsRowPresenter; 3922eaa9441bf3a521bfafb160674ff2da421eded8Dake Guimport android.support.v17.leanback.widget.Presenter; 4022eaa9441bf3a521bfafb160674ff2da421eded8Dake Guimport android.support.v17.leanback.widget.PresenterSelector; 4122eaa9441bf3a521bfafb160674ff2da421eded8Dake Guimport android.support.v17.leanback.widget.RowPresenter; 4222eaa9441bf3a521bfafb160674ff2da421eded8Dake Guimport android.support.v17.leanback.widget.VerticalGridView; 43372d07bb41510d91a6a662a1906aceb0ee759481Craig Stoutimport android.util.Log; 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; 497ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout 502d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stoutimport java.util.ArrayList; 517ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout 527ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout/** 537ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout * A fragment for displaying playback controls and related content. 54a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * <p> 55a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * A PlaybackOverlayFragment renders the elements of its {@link ObjectAdapter} as a set 5622eaa9441bf3a521bfafb160674ff2da421eded8Dake Gu * of rows in a vertical list. The Adapter's {@link PresenterSelector} must maintain subclasses 5722eaa9441bf3a521bfafb160674ff2da421eded8Dake Gu * of {@link RowPresenter}. 58a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * </p> 59a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * <p> 60a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * An instance of {@link android.support.v17.leanback.widget.PlaybackControlsRow} is expected to be 616dca725412977bb56b933bdec120e31909233cdbCraig Stout * at position 0 in the adapter. 62a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * </p> 637ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout */ 647ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stoutpublic class PlaybackOverlayFragment extends DetailsFragment { 657ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout 667709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout /** 677709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout * No background. 687709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout */ 697709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout public static final int BG_NONE = 0; 707709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout 717709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout /** 727709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout * A dark translucent background. 737709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout */ 747709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout public static final int BG_DARK = 1; 757709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout 767709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout /** 777709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout * A light translucent background. 787709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout */ 797709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout public static final int BG_LIGHT = 2; 807709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout 81a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout /** 82a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * Listener allowing the application to receive notification of fade in and/or fade out 83a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * completion events. 84a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout */ 85372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout public static class OnFadeCompleteListener { 86372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout public void onFadeInComplete() { 87372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout } 88372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout public void onFadeOutComplete() { 89372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout } 90372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout } 91372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout 92a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout /** 93a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * Interface allowing the application to handle input events. 94a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout */ 95eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout public interface InputEventHandler { 96eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout /** 97eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout * Called when an {@link InputEvent} is received. 98eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout * 99eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout * @return If the event should be consumed, return true. To allow the event to 100eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout * continue on to the next handler, return false. 101eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout */ 102eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout public boolean handleInputEvent(InputEvent event); 103eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout } 104eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout 105372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout private static final String TAG = "PlaybackOverlayFragment"; 106372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout private static final boolean DEBUG = false; 107d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout private static final int ANIMATION_MULTIPLIER = 1; 108372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout 109372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout private static int START_FADE_OUT = 1; 110372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout 111372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout // Fading status 112372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout private static final int IDLE = 0; 113372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout private static final int IN = 1; 114372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout private static final int OUT = 2; 115372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout 1164fe538f2d65eefc57f618887ccb1226ec1a9741dKeyvan Amiri private int mPaddingTop; 117d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout private int mPaddingBottom; 1187709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout private View mRootView; 1197709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout private int mBackgroundType = BG_DARK; 1207709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout private int mBgDarkColor; 1217709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout private int mBgLightColor; 122372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout private int mShowTimeMs; 1236b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout private int mMajorFadeTranslateY, mMinorFadeTranslateY; 1246b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout private int mAnimationTranslateY; 125372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout private OnFadeCompleteListener mFadeCompleteListener; 126eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout private InputEventHandler mInputEventHandler; 127372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout private boolean mFadingEnabled = true; 128372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout private int mFadingStatus = IDLE; 129d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout private int mBgAlpha; 130d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout private ValueAnimator mBgFadeInAnimator, mBgFadeOutAnimator; 131d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout private ValueAnimator mControlRowFadeInAnimator, mControlRowFadeOutAnimator; 1326b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout private ValueAnimator mDescriptionFadeInAnimator, mDescriptionFadeOutAnimator; 133d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout private ValueAnimator mOtherRowFadeInAnimator, mOtherRowFadeOutAnimator; 134d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout private boolean mTranslateAnimationEnabled; 135aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout private boolean mResetControlsToPrimaryActionsPending; 136d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout private RecyclerView.ItemAnimator mItemAnimator; 137372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout 138372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout private final Animator.AnimatorListener mFadeListener = 139372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout new Animator.AnimatorListener() { 140372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout @Override 141372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout public void onAnimationStart(Animator animation) { 142d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout enableVerticalGridAnimations(false); 143372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout } 144372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout @Override 145372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout public void onAnimationRepeat(Animator animation) { 146372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout } 147372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout @Override 148372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout public void onAnimationCancel(Animator animation) { 149372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout } 150372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout @Override 151372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout public void onAnimationEnd(Animator animation) { 152d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout if (DEBUG) Log.v(TAG, "onAnimationEnd " + mBgAlpha); 153d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout if (mBgAlpha > 0) { 154d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout enableVerticalGridAnimations(true); 155372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout startFadeTimer(); 156372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout if (mFadeCompleteListener != null) { 157372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout mFadeCompleteListener.onFadeInComplete(); 158372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout } 159d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout } else { 1601e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout if (getVerticalGridView() != null) { 1611e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout // Reset focus to the controls row 1621e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout getVerticalGridView().setSelectedPosition(0); 163aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout resetControlsToPrimaryActions(null); 1641e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout } 165d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout if (mFadeCompleteListener != null) { 166d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout mFadeCompleteListener.onFadeOutComplete(); 167d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout } 168372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout } 169372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout mFadingStatus = IDLE; 170372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout } 171372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout }; 172372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout 173372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout private final Handler mHandler = new Handler() { 174372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout @Override 175372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout public void handleMessage(Message message) { 176372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout if (message.what == START_FADE_OUT && mFadingEnabled) { 177372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout fade(false); 178372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout } 179372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout } 180372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout }; 181372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout 182372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout private final VerticalGridView.OnTouchInterceptListener mOnTouchInterceptListener = 183372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout new VerticalGridView.OnTouchInterceptListener() { 18415375aa6fd54b036f97f99229aefab2822c8a1c9Aurimas Liutikas @Override 185372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout public boolean onInterceptTouchEvent(MotionEvent event) { 186cbfc318baee2fc054af4c723bfac0fd3c28a1667Craig Stout return onInterceptInputEvent(event); 187372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout } 188372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout }; 189372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout 190372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout private final VerticalGridView.OnKeyInterceptListener mOnKeyInterceptListener = 191372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout new VerticalGridView.OnKeyInterceptListener() { 19215375aa6fd54b036f97f99229aefab2822c8a1c9Aurimas Liutikas @Override 193372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout public boolean onInterceptKeyEvent(KeyEvent event) { 194cbfc318baee2fc054af4c723bfac0fd3c28a1667Craig Stout return onInterceptInputEvent(event); 195372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout } 196372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout }; 197372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout 198d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout private void setBgAlpha(int alpha) { 199d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout mBgAlpha = alpha; 2001e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout if (mRootView != null) { 2011e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout mRootView.getBackground().setAlpha(alpha); 2021e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout } 203d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout } 204d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout 205d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout private void enableVerticalGridAnimations(boolean enable) { 206aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout if (getVerticalGridView() != null) { 207aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout getVerticalGridView().setAnimateChildLayout(enable); 208aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout } 209aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout } 210aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout 211aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout private void resetControlsToPrimaryActions(ItemBridgeAdapter.ViewHolder vh) { 212aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout if (vh == null && getVerticalGridView() != null) { 213aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout vh = (ItemBridgeAdapter.ViewHolder) getVerticalGridView().findViewHolderForPosition(0); 2141e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout } 215aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout if (vh == null) { 216aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout mResetControlsToPrimaryActionsPending = true; 217aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout } else if (vh.getPresenter() instanceof PlaybackControlsRowPresenter) { 218aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout mResetControlsToPrimaryActionsPending = false; 219aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout ((PlaybackControlsRowPresenter) vh.getPresenter()).showPrimaryActions( 220aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout (PlaybackControlsRowPresenter.ViewHolder) vh.getViewHolder()); 221d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout } 222d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout } 223d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout 224372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout /** 225372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout * Enables or disables view fading. If enabled, 226372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout * the view will be faded in when the fragment starts, 227372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout * and will fade out after a time period. The timeout 228372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout * period is reset each time {@link #tickle} is called. 229372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout * 230372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout */ 231372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout public void setFadingEnabled(boolean enabled) { 232372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout if (DEBUG) Log.v(TAG, "setFadingEnabled " + enabled); 233372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout if (enabled != mFadingEnabled) { 234372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout mFadingEnabled = enabled; 235f47fb1e34efd538c322f7539893272ba847cdbdcCraig Stout if (mFadingEnabled) { 236f47fb1e34efd538c322f7539893272ba847cdbdcCraig Stout if (isResumed() && mFadingStatus == IDLE 237f47fb1e34efd538c322f7539893272ba847cdbdcCraig Stout && !mHandler.hasMessages(START_FADE_OUT)) { 238f47fb1e34efd538c322f7539893272ba847cdbdcCraig Stout startFadeTimer(); 239372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout } 240f47fb1e34efd538c322f7539893272ba847cdbdcCraig Stout } else { 241f47fb1e34efd538c322f7539893272ba847cdbdcCraig Stout // Ensure fully opaque 242f47fb1e34efd538c322f7539893272ba847cdbdcCraig Stout mHandler.removeMessages(START_FADE_OUT); 243f47fb1e34efd538c322f7539893272ba847cdbdcCraig Stout fade(true); 244372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout } 245372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout } 246372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout } 247372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout 248372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout /** 249372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout * Returns true if view fading is enabled. 250372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout */ 251372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout public boolean isFadingEnabled() { 252372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout return mFadingEnabled; 253372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout } 254372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout 255372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout /** 256372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout * Sets the listener to be called when fade in or out has completed. 257372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout */ 258372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout public void setFadeCompleteListener(OnFadeCompleteListener listener) { 259372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout mFadeCompleteListener = listener; 260372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout } 261372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout 262372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout /** 263372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout * Returns the listener to be called when fade in or out has completed. 264372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout */ 265372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout public OnFadeCompleteListener getFadeCompleteListener() { 266372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout return mFadeCompleteListener; 267372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout } 268372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout 269372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout /** 270eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout * Sets the input event handler. 271eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout */ 272eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout public final void setInputEventHandler(InputEventHandler handler) { 273eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout mInputEventHandler = handler; 274eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout } 275eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout 276eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout /** 277eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout * Returns the input event handler. 278eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout */ 2792dfed05c8ab53ca7c28424c9c03b1a87b9b7ca0dCraig Stout public final InputEventHandler getInputEventHandler() { 280eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout return mInputEventHandler; 281eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout } 282eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout 283eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout /** 284372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout * Tickles the playback controls. Fades in the view if it was faded out, 285372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout * otherwise resets the fade out timer. Tickling on input events is handled 286372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout * by the fragment. 287372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout */ 288372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout public void tickle() { 289372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout if (DEBUG) Log.v(TAG, "tickle enabled " + mFadingEnabled + " isResumed " + isResumed()); 290372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout if (!mFadingEnabled || !isResumed()) { 291372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout return; 292372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout } 293372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout if (mHandler.hasMessages(START_FADE_OUT)) { 294372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout // Restart the timer 295372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout startFadeTimer(); 296372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout } else { 297372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout fade(true); 298372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout } 299372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout } 300372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout 30191e100e4450b6101a674d8a3ab15e426fc5294bcDongwon Kang /** 30291e100e4450b6101a674d8a3ab15e426fc5294bcDongwon Kang * Fades out the playback overlay immediately. 30391e100e4450b6101a674d8a3ab15e426fc5294bcDongwon Kang */ 30491e100e4450b6101a674d8a3ab15e426fc5294bcDongwon Kang public void fadeOut() { 30591e100e4450b6101a674d8a3ab15e426fc5294bcDongwon Kang mHandler.removeMessages(START_FADE_OUT); 30691e100e4450b6101a674d8a3ab15e426fc5294bcDongwon Kang fade(false); 30791e100e4450b6101a674d8a3ab15e426fc5294bcDongwon Kang } 30891e100e4450b6101a674d8a3ab15e426fc5294bcDongwon Kang 30960bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout private boolean areControlsHidden() { 31060bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout return mFadingStatus == IDLE && mBgAlpha == 0; 311cbfc318baee2fc054af4c723bfac0fd3c28a1667Craig Stout } 312cbfc318baee2fc054af4c723bfac0fd3c28a1667Craig Stout 313cbfc318baee2fc054af4c723bfac0fd3c28a1667Craig Stout private boolean onInterceptInputEvent(InputEvent event) { 31460bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout final boolean controlsHidden = areControlsHidden(); 31560bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout if (DEBUG) Log.v(TAG, "onInterceptInputEvent hidden " + controlsHidden + " " + event); 31660bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout boolean consumeEvent = false; 317c92c356de1a687598a031f3452053dc6c9af9b77Craig Stout int keyCode = KeyEvent.KEYCODE_UNKNOWN; 318c92c356de1a687598a031f3452053dc6c9af9b77Craig Stout 31960bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout if (mInputEventHandler != null) { 32060bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout consumeEvent = mInputEventHandler.handleInputEvent(event); 32160bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout } 322cbfc318baee2fc054af4c723bfac0fd3c28a1667Craig Stout if (event instanceof KeyEvent) { 323c92c356de1a687598a031f3452053dc6c9af9b77Craig Stout keyCode = ((KeyEvent) event).getKeyCode(); 324c92c356de1a687598a031f3452053dc6c9af9b77Craig Stout } 32560bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout 32660bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout switch (keyCode) { 32760bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout case KeyEvent.KEYCODE_DPAD_CENTER: 32860bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout case KeyEvent.KEYCODE_DPAD_DOWN: 32960bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout case KeyEvent.KEYCODE_DPAD_UP: 33060bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout case KeyEvent.KEYCODE_DPAD_LEFT: 33160bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout case KeyEvent.KEYCODE_DPAD_RIGHT: 33260bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout // Event may be consumed; regardless, if controls are hidden then these keys will 33360bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout // bring up the controls. 33460bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout if (controlsHidden) { 33560bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout consumeEvent = true; 33660bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout } 337cbfc318baee2fc054af4c723bfac0fd3c28a1667Craig Stout tickle(); 33860bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout break; 33960bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout case KeyEvent.KEYCODE_BACK: 340c89266e21f0269aecd5df2dc2a39f6f0cf11a58eCraig Stout case KeyEvent.KEYCODE_ESCAPE: 34160bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout // If fading enabled and controls are not hidden, back will be consumed to fade 34260bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout // them out (even if the key was consumed by the handler). 34360bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout if (mFadingEnabled && !controlsHidden) { 34460bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout consumeEvent = true; 34560bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout mHandler.removeMessages(START_FADE_OUT); 34660bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout fade(false); 34760bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout } else if (consumeEvent) { 34860bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout tickle(); 34960bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout } 35060bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout break; 35160bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout default: 35260bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout if (consumeEvent) { 35360bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout tickle(); 35460bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout } 355eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout } 356372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout return consumeEvent; 357372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout } 358372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout 359372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout @Override 360372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout public void onResume() { 361372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout super.onResume(); 362372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout if (mFadingEnabled) { 363d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout setBgAlpha(0); 364372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout fade(true); 365372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout } 366372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout getVerticalGridView().setOnTouchInterceptListener(mOnTouchInterceptListener); 367372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout getVerticalGridView().setOnKeyInterceptListener(mOnKeyInterceptListener); 368372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout } 369372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout 370372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout private void startFadeTimer() { 3711e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout if (mHandler != null) { 3721e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout mHandler.removeMessages(START_FADE_OUT); 3731e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout mHandler.sendEmptyMessageDelayed(START_FADE_OUT, mShowTimeMs); 3741e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout } 375372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout } 376372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout 377d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout private static ValueAnimator loadAnimator(Context context, int resId) { 378d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout ValueAnimator animator = (ValueAnimator) AnimatorInflater.loadAnimator(context, resId); 379d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout animator.setDuration(animator.getDuration() * ANIMATION_MULTIPLIER); 380d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout return animator; 381d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout } 382d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout 383d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout private void loadBgAnimator() { 384d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout AnimatorUpdateListener listener = new AnimatorUpdateListener() { 385d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout @Override 386d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout public void onAnimationUpdate(ValueAnimator arg0) { 387d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout setBgAlpha((Integer) arg0.getAnimatedValue()); 388d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout } 389d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout }; 390d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout 391d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout mBgFadeInAnimator = loadAnimator(getActivity(), R.animator.lb_playback_bg_fade_in); 392d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout mBgFadeInAnimator.addUpdateListener(listener); 393d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout mBgFadeInAnimator.addListener(mFadeListener); 394d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout 395d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout mBgFadeOutAnimator = loadAnimator(getActivity(), R.animator.lb_playback_bg_fade_out); 396d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout mBgFadeOutAnimator.addUpdateListener(listener); 397d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout mBgFadeOutAnimator.addListener(mFadeListener); 398d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout } 399d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout 400d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout private TimeInterpolator mLogDecelerateInterpolator = new LogDecelerateInterpolator(100,0); 401d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout private TimeInterpolator mLogAccelerateInterpolator = new LogAccelerateInterpolator(100,0); 402d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout 4032d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout private View getControlRowView() { 4042d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout if (getVerticalGridView() == null) { 4052d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout return null; 4062d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout } 4072d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout RecyclerView.ViewHolder vh = getVerticalGridView().findViewHolderForPosition(0); 4082d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout if (vh == null) { 4092d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout return null; 4102d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout } 4112d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout return vh.itemView; 4122d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout } 4132d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout 414d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout private void loadControlRowAnimator() { 4152d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout final AnimatorListener listener = new AnimatorListener() { 416d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout @Override 4172d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout void getViews(ArrayList<View> views) { 4182d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout View view = getControlRowView(); 4192d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout if (view != null) { 4202d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout views.add(view); 4211e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout } 4222d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout } 4232d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout }; 4242d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout final AnimatorUpdateListener updateListener = new AnimatorUpdateListener() { 4252d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout @Override 4262d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout public void onAnimationUpdate(ValueAnimator arg0) { 4272d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout View view = getControlRowView(); 4282d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout if (view != null) { 429d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout final float fraction = (Float) arg0.getAnimatedValue(); 430d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout if (DEBUG) Log.v(TAG, "fraction " + fraction); 4312d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout view.setAlpha(fraction); 4322d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout view.setTranslationY((float) mAnimationTranslateY * (1f - fraction)); 433d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout } 434d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout } 435d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout }; 436d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout 437d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout mControlRowFadeInAnimator = loadAnimator( 438d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout getActivity(), R.animator.lb_playback_controls_fade_in); 4392d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout mControlRowFadeInAnimator.addUpdateListener(updateListener); 4402d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout mControlRowFadeInAnimator.addListener(listener); 441d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout mControlRowFadeInAnimator.setInterpolator(mLogDecelerateInterpolator); 442d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout 443d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout mControlRowFadeOutAnimator = loadAnimator( 444d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout getActivity(), R.animator.lb_playback_controls_fade_out); 4452d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout mControlRowFadeOutAnimator.addUpdateListener(updateListener); 4462d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout mControlRowFadeOutAnimator.addListener(listener); 447d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout mControlRowFadeOutAnimator.setInterpolator(mLogAccelerateInterpolator); 448d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout } 449d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout 450d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout private void loadOtherRowAnimator() { 4512d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout final AnimatorListener listener = new AnimatorListener() { 452d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout @Override 4532d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout void getViews(ArrayList<View> views) { 4541e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout if (getVerticalGridView() == null) { 4551e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout return; 4561e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout } 457d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout final int count = getVerticalGridView().getChildCount(); 458d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout for (int i = 0; i < count; i++) { 459d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout View view = getVerticalGridView().getChildAt(i); 4602d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout if (view != null) { 4612d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout views.add(view); 4622d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout } 4632d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout } 4642d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout } 4652d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout }; 4662d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout final AnimatorUpdateListener updateListener = new AnimatorUpdateListener() { 4672d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout @Override 4682d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout public void onAnimationUpdate(ValueAnimator arg0) { 4691df1f18de496764a0c922053e601d1b6d6d3f31cCraig Stout if (getVerticalGridView() == null) { 4701df1f18de496764a0c922053e601d1b6d6d3f31cCraig Stout return; 4711df1f18de496764a0c922053e601d1b6d6d3f31cCraig Stout } 4722d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout final float fraction = (Float) arg0.getAnimatedValue(); 4732d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout for (View view : listener.mViews) { 474d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout if (getVerticalGridView().getChildPosition(view) > 0) { 475d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout view.setAlpha(fraction); 4766b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout view.setTranslationY((float) mAnimationTranslateY * (1f - fraction)); 477d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout } 478d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout } 479d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout } 480d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout }; 481d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout 482d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout mOtherRowFadeInAnimator = loadAnimator( 483d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout getActivity(), R.animator.lb_playback_controls_fade_in); 4842d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout mOtherRowFadeInAnimator.addListener(listener); 4852d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout mOtherRowFadeInAnimator.addUpdateListener(updateListener); 486d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout mOtherRowFadeInAnimator.setInterpolator(mLogDecelerateInterpolator); 487d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout 488d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout mOtherRowFadeOutAnimator = loadAnimator( 489d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout getActivity(), R.animator.lb_playback_controls_fade_out); 4902d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout mOtherRowFadeOutAnimator.addListener(listener); 4912d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout mOtherRowFadeOutAnimator.addUpdateListener(updateListener); 4926b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout mOtherRowFadeOutAnimator.setInterpolator(new AccelerateInterpolator()); 4936b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout } 4946b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout 4956b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout private void loadDescriptionAnimator() { 4966b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout AnimatorUpdateListener listener = new AnimatorUpdateListener() { 4976b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout @Override 4986b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout public void onAnimationUpdate(ValueAnimator arg0) { 4996b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout if (getVerticalGridView() == null) { 5006b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout return; 5016b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout } 5026b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout ItemBridgeAdapter.ViewHolder adapterVh = (ItemBridgeAdapter.ViewHolder) 5036b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout getVerticalGridView().findViewHolderForPosition(0); 5046b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout if (adapterVh != null && adapterVh.getViewHolder() 5056b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout instanceof PlaybackControlsRowPresenter.ViewHolder) { 5066b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout final Presenter.ViewHolder vh = ((PlaybackControlsRowPresenter.ViewHolder) 5076b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout adapterVh.getViewHolder()).mDescriptionViewHolder; 5088f5c183ba7b9df6b5339586f51219b4d5e6305f3Craig Stout if (vh != null) { 5098f5c183ba7b9df6b5339586f51219b4d5e6305f3Craig Stout vh.view.setAlpha((Float) arg0.getAnimatedValue()); 5108f5c183ba7b9df6b5339586f51219b4d5e6305f3Craig Stout } 5116b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout } 5126b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout } 5136b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout }; 5146b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout 5156b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout mDescriptionFadeInAnimator = loadAnimator( 5166b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout getActivity(), R.animator.lb_playback_description_fade_in); 5176b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout mDescriptionFadeInAnimator.addUpdateListener(listener); 5186b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout mDescriptionFadeInAnimator.setInterpolator(mLogDecelerateInterpolator); 5196b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout 5206b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout mDescriptionFadeOutAnimator = loadAnimator( 5216b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout getActivity(), R.animator.lb_playback_description_fade_out); 5226b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout mDescriptionFadeOutAnimator.addUpdateListener(listener); 523d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout } 524d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout 525372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout private void fade(boolean fadeIn) { 526372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout if (DEBUG) Log.v(TAG, "fade " + fadeIn); 527372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout if (getView() == null) { 528372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout return; 529372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout } 530372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout if ((fadeIn && mFadingStatus == IN) || (!fadeIn && mFadingStatus == OUT)) { 531d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout if (DEBUG) Log.v(TAG, "requested fade in progress"); 532d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout return; 533d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout } 534d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout if ((fadeIn && mBgAlpha == 255) || (!fadeIn && mBgAlpha == 0)) { 535d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout if (DEBUG) Log.v(TAG, "fade is no-op"); 536372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout return; 537372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout } 538372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout 5396b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout mAnimationTranslateY = getVerticalGridView().getSelectedPosition() == 0 ? 5406b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout mMajorFadeTranslateY : mMinorFadeTranslateY; 541d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout 542d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout if (mFadingStatus == IDLE) { 543d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout if (fadeIn) { 544d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout mBgFadeInAnimator.start(); 545d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout mControlRowFadeInAnimator.start(); 546d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout mOtherRowFadeInAnimator.start(); 5476b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout mDescriptionFadeInAnimator.start(); 548d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout } else { 549d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout mBgFadeOutAnimator.start(); 550d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout mControlRowFadeOutAnimator.start(); 551d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout mOtherRowFadeOutAnimator.start(); 5526b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout mDescriptionFadeOutAnimator.start(); 553d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout } 554d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout } else { 555d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout if (fadeIn) { 556d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout mBgFadeOutAnimator.reverse(); 557d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout mControlRowFadeOutAnimator.reverse(); 558d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout mOtherRowFadeOutAnimator.reverse(); 5596b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout mDescriptionFadeOutAnimator.reverse(); 560d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout } else { 561d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout mBgFadeInAnimator.reverse(); 562d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout mControlRowFadeInAnimator.reverse(); 563d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout mOtherRowFadeInAnimator.reverse(); 5646b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout mDescriptionFadeInAnimator.reverse(); 565d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout } 566d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout } 567d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout 568d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout // If fading in while control row is focused, set initial translationY so 569d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout // views slide in from below. 5706b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout if (fadeIn && mFadingStatus == IDLE) { 571d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout final int count = getVerticalGridView().getChildCount(); 572d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout for (int i = 0; i < count; i++) { 5736b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout getVerticalGridView().getChildAt(i).setTranslationY(mAnimationTranslateY); 574d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout } 575d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout } 576d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout 577372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout mFadingStatus = fadeIn ? IN : OUT; 578372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout } 5797ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout 5807ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout /** 5817ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout * Sets the list of rows for the fragment. 5827ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout */ 5837ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout @Override 5847ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout public void setAdapter(ObjectAdapter adapter) { 5856dca725412977bb56b933bdec120e31909233cdbCraig Stout if (getAdapter() != null) { 5866dca725412977bb56b933bdec120e31909233cdbCraig Stout getAdapter().unregisterObserver(mObserver); 5876dca725412977bb56b933bdec120e31909233cdbCraig Stout } 5887ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout super.setAdapter(adapter); 5896dca725412977bb56b933bdec120e31909233cdbCraig Stout if (adapter != null) { 5906dca725412977bb56b933bdec120e31909233cdbCraig Stout adapter.registerObserver(mObserver); 5916dca725412977bb56b933bdec120e31909233cdbCraig Stout } 5927ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout } 5937ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout 5947ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout @Override 5957ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout void setVerticalGridViewLayout(VerticalGridView listview) { 596d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout if (listview == null) { 5977ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout return; 5987ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout } 599d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout // Padding affects alignment when last row is focused 600d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout // (last is first when there's only one row). 6014fe538f2d65eefc57f618887ccb1226ec1a9741dKeyvan Amiri setPadding(listview, mPaddingTop, mPaddingBottom); 602d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout 603d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout // Item alignment affects focused row that isn't the last. 6044fe538f2d65eefc57f618887ccb1226ec1a9741dKeyvan Amiri listview.setItemAlignmentOffset(0); 6054fe538f2d65eefc57f618887ccb1226ec1a9741dKeyvan Amiri listview.setItemAlignmentOffsetPercent(50); 606d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout 607d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout // Push rows to the bottom. 6087ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout listview.setWindowAlignmentOffset(0); 6094fe538f2d65eefc57f618887ccb1226ec1a9741dKeyvan Amiri listview.setWindowAlignmentOffsetPercent(50); 6104fe538f2d65eefc57f618887ccb1226ec1a9741dKeyvan Amiri listview.setWindowAlignment(VerticalGridView.WINDOW_ALIGN_BOTH_EDGE); 6117ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout } 6127ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout 6134fe538f2d65eefc57f618887ccb1226ec1a9741dKeyvan Amiri private static void setPadding(View view, int paddingTop, int paddingBottom) { 6144fe538f2d65eefc57f618887ccb1226ec1a9741dKeyvan Amiri view.setPadding(view.getPaddingLeft(), paddingTop, 6154fe538f2d65eefc57f618887ccb1226ec1a9741dKeyvan Amiri view.getPaddingRight(), paddingBottom); 616d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout } 617d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout 6187ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout @Override 6197ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout public void onCreate(Bundle savedInstanceState) { 6207ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout super.onCreate(savedInstanceState); 6217ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout 6224fe538f2d65eefc57f618887ccb1226ec1a9741dKeyvan Amiri mPaddingTop = 6234fe538f2d65eefc57f618887ccb1226ec1a9741dKeyvan Amiri getResources().getDimensionPixelSize(R.dimen.lb_playback_controls_padding_top); 624d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout mPaddingBottom = 625d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout getResources().getDimensionPixelSize(R.dimen.lb_playback_controls_padding_bottom); 6267709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout mBgDarkColor = 6277709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout getResources().getColor(R.color.lb_playback_controls_background_dark); 6287709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout mBgLightColor = 6297709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout getResources().getColor(R.color.lb_playback_controls_background_light); 630372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout mShowTimeMs = 631372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout getResources().getInteger(R.integer.lb_playback_controls_show_time_ms); 6326b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout mMajorFadeTranslateY = 6336b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout getResources().getDimensionPixelSize(R.dimen.lb_playback_major_fade_translate_y); 6346b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout mMinorFadeTranslateY = 6356b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout getResources().getDimensionPixelSize(R.dimen.lb_playback_minor_fade_translate_y); 636d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout 637d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout loadBgAnimator(); 638d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout loadControlRowAnimator(); 639d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout loadOtherRowAnimator(); 6406b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout loadDescriptionAnimator(); 6417709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout } 6427709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout 6437709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout /** 6447709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout * Sets the background type. 6457709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout * 6467709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout * @param type One of BG_LIGHT, BG_DARK, or BG_NONE. 6477709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout */ 6487709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout public void setBackgroundType(int type) { 649372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout switch (type) { 650372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout case BG_LIGHT: 651372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout case BG_DARK: 652372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout case BG_NONE: 653372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout if (type != mBackgroundType) { 654372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout mBackgroundType = type; 655372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout updateBackground(); 656372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout } 657372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout break; 658372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout default: 6597709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout throw new IllegalArgumentException("Invalid background type"); 6607709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout } 6617709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout } 6627709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout 6637709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout /** 6647709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout * Returns the background type. 6657709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout */ 6667709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout public int getBackgroundType() { 6677709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout return mBackgroundType; 6687709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout } 6697709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout 6707709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout private void updateBackground() { 6717709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout if (mRootView != null) { 6727709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout int color = mBgDarkColor; 6737709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout switch (mBackgroundType) { 6747709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout case BG_DARK: break; 6757709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout case BG_LIGHT: color = mBgLightColor; break; 6767709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout case BG_NONE: color = Color.TRANSPARENT; break; 6777709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout } 6787709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout mRootView.setBackground(new ColorDrawable(color)); 6797709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout } 6807709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout } 6817709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout 682d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout private void updateControlsBottomSpace(ItemBridgeAdapter.ViewHolder vh) { 683d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout // Add extra space between rows 0 and 1 684d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout if (vh == null && getVerticalGridView() != null) { 685d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout vh = (ItemBridgeAdapter.ViewHolder) 686d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout getVerticalGridView().findViewHolderForPosition(0); 687d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout } 688d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout if (vh != null && vh.getPresenter() instanceof PlaybackControlsRowPresenter) { 689d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout final int adapterSize = getAdapter() == null ? 0 : getAdapter().size(); 690d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout ((PlaybackControlsRowPresenter) vh.getPresenter()).showBottomSpace( 691d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout (PlaybackControlsRowPresenter.ViewHolder) vh.getViewHolder(), 692d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout adapterSize > 1); 693d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout } 694d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout } 695d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout 696d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout private final ItemBridgeAdapter.AdapterListener mAdapterListener = 697d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout new ItemBridgeAdapter.AdapterListener() { 698d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout @Override 699d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout public void onAttachedToWindow(ItemBridgeAdapter.ViewHolder vh) { 700d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout if (DEBUG) Log.v(TAG, "onAttachedToWindow " + vh.getViewHolder().view); 701d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout if ((mFadingStatus == IDLE && mBgAlpha == 0) || mFadingStatus == OUT) { 702d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout if (DEBUG) Log.v(TAG, "setting alpha to 0"); 703d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout vh.getViewHolder().view.setAlpha(0); 704d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout } 705aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout if (vh.getPosition() == 0 && mResetControlsToPrimaryActionsPending) { 706aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout resetControlsToPrimaryActions(vh); 707aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout } 708d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout } 709d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout @Override 710d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout public void onDetachedFromWindow(ItemBridgeAdapter.ViewHolder vh) { 711d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout if (DEBUG) Log.v(TAG, "onDetachedFromWindow " + vh.getViewHolder().view); 712d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout // Reset animation state 713d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout vh.getViewHolder().view.setAlpha(1f); 714d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout vh.getViewHolder().view.setTranslationY(0); 7156b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout if (vh.getViewHolder() instanceof PlaybackControlsRowPresenter.ViewHolder) { 7168f5c183ba7b9df6b5339586f51219b4d5e6305f3Craig Stout Presenter.ViewHolder descriptionVh = ((PlaybackControlsRowPresenter.ViewHolder) 7178f5c183ba7b9df6b5339586f51219b4d5e6305f3Craig Stout vh.getViewHolder()).mDescriptionViewHolder; 7188f5c183ba7b9df6b5339586f51219b4d5e6305f3Craig Stout if (descriptionVh != null) { 7198f5c183ba7b9df6b5339586f51219b4d5e6305f3Craig Stout descriptionVh.view.setAlpha(1f); 7208f5c183ba7b9df6b5339586f51219b4d5e6305f3Craig Stout } 7216b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout } 722d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout } 723d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout @Override 724d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout public void onBind(ItemBridgeAdapter.ViewHolder vh) { 725d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout if (vh.getPosition() == 0) { 726d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout updateControlsBottomSpace(vh); 727d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout } 728d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout } 729d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout }; 730d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout 7317709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout @Override 7327709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout public View onCreateView(LayoutInflater inflater, ViewGroup container, 7337709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout Bundle savedInstanceState) { 7347709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout mRootView = super.onCreateView(inflater, container, savedInstanceState); 735d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout mBgAlpha = 255; 7367709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout updateBackground(); 737d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout getRowsFragment().setExternalAdapterListener(mAdapterListener); 7387709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout return mRootView; 7397ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout } 7406dca725412977bb56b933bdec120e31909233cdbCraig Stout 7411e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout @Override 7421e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout public void onDestroyView() { 7431e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout mRootView = null; 7441e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout super.onDestroyView(); 7451e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout } 7461e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout 7476dca725412977bb56b933bdec120e31909233cdbCraig Stout private final DataObserver mObserver = new DataObserver() { 74815375aa6fd54b036f97f99229aefab2822c8a1c9Aurimas Liutikas @Override 7496dca725412977bb56b933bdec120e31909233cdbCraig Stout public void onChanged() { 750d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout updateControlsBottomSpace(null); 7516dca725412977bb56b933bdec120e31909233cdbCraig Stout } 7526dca725412977bb56b933bdec120e31909233cdbCraig Stout }; 7532d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout 7542d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout static abstract class AnimatorListener implements Animator.AnimatorListener { 7552d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout ArrayList<View> mViews = new ArrayList<View>(); 7562d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout ArrayList<Integer> mLayerType = new ArrayList<Integer>(); 7572d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout 75815375aa6fd54b036f97f99229aefab2822c8a1c9Aurimas Liutikas @Override 7592d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout public void onAnimationCancel(Animator animation) { 7602d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout } 76115375aa6fd54b036f97f99229aefab2822c8a1c9Aurimas Liutikas @Override 7622d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout public void onAnimationRepeat(Animator animation) { 7632d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout } 76415375aa6fd54b036f97f99229aefab2822c8a1c9Aurimas Liutikas @Override 7652d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout public void onAnimationStart(Animator animation) { 7662d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout getViews(mViews); 7672d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout for (View view : mViews) { 7682d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout mLayerType.add(view.getLayerType()); 7692d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout view.setLayerType(View.LAYER_TYPE_HARDWARE, null); 7702d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout } 7712d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout } 77215375aa6fd54b036f97f99229aefab2822c8a1c9Aurimas Liutikas @Override 7732d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout public void onAnimationEnd(Animator animation) { 7742d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout for (int i = 0; i < mViews.size(); i++) { 7752d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout mViews.get(i).setLayerType(mLayerType.get(i), null); 7762d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout } 7772d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout mLayerType.clear(); 7782d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout mViews.clear(); 7792d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout } 7802d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout abstract void getViews(ArrayList<View> views); 7814fe538f2d65eefc57f618887ccb1226ec1a9741dKeyvan Amiri 7822d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout }; 7837ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout} 784