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