PlaybackOverlayFragment.java revision 60bb6af2e336072921f5d3c3861e86b3cc6241b3
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; 2460bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stoutimport android.support.v17.leanback.widget.Row; 25cbfc318baee2fc054af4c723bfac0fd3c28a1667Craig Stoutimport android.view.InputEvent; 266b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stoutimport android.view.animation.AccelerateInterpolator; 27d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stoutimport android.animation.ValueAnimator.AnimatorUpdateListener; 28d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stoutimport android.content.Context; 297ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stoutimport android.os.Bundle; 30372d07bb41510d91a6a662a1906aceb0ee759481Craig Stoutimport android.os.Handler; 31372d07bb41510d91a6a662a1906aceb0ee759481Craig Stoutimport android.os.Message; 32d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stoutimport android.support.v7.widget.RecyclerView; 337ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stoutimport android.support.v17.leanback.R; 34d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stoutimport android.support.v17.leanback.animation.LogAccelerateInterpolator; 35d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stoutimport android.support.v17.leanback.animation.LogDecelerateInterpolator; 366b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stoutimport android.support.v17.leanback.widget.Presenter; 37d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stoutimport android.support.v17.leanback.widget.ItemBridgeAdapter; 387ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stoutimport android.support.v17.leanback.widget.ObjectAdapter; 396dca725412977bb56b933bdec120e31909233cdbCraig Stoutimport android.support.v17.leanback.widget.ObjectAdapter.DataObserver; 407ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stoutimport android.support.v17.leanback.widget.VerticalGridView; 416b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stoutimport android.support.v17.leanback.widget.PlaybackControlsRowPresenter; 42372d07bb41510d91a6a662a1906aceb0ee759481Craig Stoutimport android.util.Log; 43372d07bb41510d91a6a662a1906aceb0ee759481Craig Stoutimport android.view.KeyEvent; 447709709c2c78490a21311e9950d5dca7e89a6aedCraig Stoutimport android.view.LayoutInflater; 45372d07bb41510d91a6a662a1906aceb0ee759481Craig Stoutimport android.view.MotionEvent; 467709709c2c78490a21311e9950d5dca7e89a6aedCraig Stoutimport android.view.View; 477709709c2c78490a21311e9950d5dca7e89a6aedCraig Stoutimport android.view.ViewGroup; 487ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout 492d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stoutimport java.util.ArrayList; 507ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout 517ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout/** 527ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout * A fragment for displaying playback controls and related content. 536dca725412977bb56b933bdec120e31909233cdbCraig Stout * The {@link android.support.v17.leanback.widget.PlaybackControlsRow} is expected to be 546dca725412977bb56b933bdec120e31909233cdbCraig Stout * at position 0 in the adapter. 557ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout */ 567ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stoutpublic class PlaybackOverlayFragment extends DetailsFragment { 577ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout 587709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout /** 597709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout * No background. 607709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout */ 617709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout public static final int BG_NONE = 0; 627709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout 637709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout /** 647709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout * A dark translucent background. 657709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout */ 667709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout public static final int BG_DARK = 1; 677709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout 687709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout /** 697709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout * A light translucent background. 707709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout */ 717709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout public static final int BG_LIGHT = 2; 727709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout 73372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout public static class OnFadeCompleteListener { 74372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout public void onFadeInComplete() { 75372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout } 76372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout public void onFadeOutComplete() { 77372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout } 78372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout } 79372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout 80eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout public interface InputEventHandler { 81eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout /** 82eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout * Called when an {@link InputEvent} is received. 83eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout * 84eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout * @return If the event should be consumed, return true. To allow the event to 85eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout * continue on to the next handler, return false. 86eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout */ 87eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout public boolean handleInputEvent(InputEvent event); 88eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout } 89eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout 90372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout private static final String TAG = "PlaybackOverlayFragment"; 91372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout private static final boolean DEBUG = false; 92d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout private static final int ANIMATION_MULTIPLIER = 1; 93372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout 94372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout private static int START_FADE_OUT = 1; 95372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout 96372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout // Fading status 97372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout private static final int IDLE = 0; 98372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout private static final int IN = 1; 99372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout private static final int OUT = 2; 100372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout 1017ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout private int mAlignPosition; 102d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout private int mPaddingBottom; 1037709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout private View mRootView; 1047709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout private int mBackgroundType = BG_DARK; 1057709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout private int mBgDarkColor; 1067709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout private int mBgLightColor; 107372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout private int mShowTimeMs; 1086b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout private int mMajorFadeTranslateY, mMinorFadeTranslateY; 1096b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout private int mAnimationTranslateY; 110372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout private OnFadeCompleteListener mFadeCompleteListener; 111eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout private InputEventHandler mInputEventHandler; 112372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout private boolean mFadingEnabled = true; 113372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout private int mFadingStatus = IDLE; 114d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout private int mBgAlpha; 115d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout private ValueAnimator mBgFadeInAnimator, mBgFadeOutAnimator; 116d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout private ValueAnimator mControlRowFadeInAnimator, mControlRowFadeOutAnimator; 1176b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout private ValueAnimator mDescriptionFadeInAnimator, mDescriptionFadeOutAnimator; 118d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout private ValueAnimator mOtherRowFadeInAnimator, mOtherRowFadeOutAnimator; 119d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout private boolean mTranslateAnimationEnabled; 120aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout private boolean mResetControlsToPrimaryActionsPending; 121d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout private RecyclerView.ItemAnimator mItemAnimator; 122372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout 123372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout private final Animator.AnimatorListener mFadeListener = 124372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout new Animator.AnimatorListener() { 125372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout @Override 126372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout public void onAnimationStart(Animator animation) { 127d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout enableVerticalGridAnimations(false); 128372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout } 129372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout @Override 130372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout public void onAnimationRepeat(Animator animation) { 131372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout } 132372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout @Override 133372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout public void onAnimationCancel(Animator animation) { 134372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout } 135372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout @Override 136372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout public void onAnimationEnd(Animator animation) { 137d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout if (DEBUG) Log.v(TAG, "onAnimationEnd " + mBgAlpha); 138d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout if (mBgAlpha > 0) { 139d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout enableVerticalGridAnimations(true); 140372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout startFadeTimer(); 141372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout if (mFadeCompleteListener != null) { 142372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout mFadeCompleteListener.onFadeInComplete(); 143372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout } 144d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout } else { 1451e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout if (getVerticalGridView() != null) { 1461e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout // Reset focus to the controls row 1471e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout getVerticalGridView().setSelectedPosition(0); 148aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout resetControlsToPrimaryActions(null); 1491e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout } 150d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout if (mFadeCompleteListener != null) { 151d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout mFadeCompleteListener.onFadeOutComplete(); 152d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout } 153372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout } 154372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout mFadingStatus = IDLE; 155372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout } 156372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout }; 157372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout 158372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout private final Handler mHandler = new Handler() { 159372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout @Override 160372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout public void handleMessage(Message message) { 161372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout if (message.what == START_FADE_OUT && mFadingEnabled) { 162372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout fade(false); 163372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout } 164372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout } 165372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout }; 166372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout 167372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout private final VerticalGridView.OnTouchInterceptListener mOnTouchInterceptListener = 168372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout new VerticalGridView.OnTouchInterceptListener() { 169372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout public boolean onInterceptTouchEvent(MotionEvent event) { 170cbfc318baee2fc054af4c723bfac0fd3c28a1667Craig Stout return onInterceptInputEvent(event); 171372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout } 172372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout }; 173372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout 174372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout private final VerticalGridView.OnKeyInterceptListener mOnKeyInterceptListener = 175372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout new VerticalGridView.OnKeyInterceptListener() { 176372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout public boolean onInterceptKeyEvent(KeyEvent event) { 177cbfc318baee2fc054af4c723bfac0fd3c28a1667Craig Stout return onInterceptInputEvent(event); 178372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout } 179372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout }; 180372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout 181d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout private void setBgAlpha(int alpha) { 182d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout mBgAlpha = alpha; 1831e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout if (mRootView != null) { 1841e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout mRootView.getBackground().setAlpha(alpha); 1851e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout } 186d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout } 187d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout 188d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout private void enableVerticalGridAnimations(boolean enable) { 189aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout if (getVerticalGridView() != null) { 190aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout getVerticalGridView().setAnimateChildLayout(enable); 191aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout } 192aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout } 193aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout 194aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout private void resetControlsToPrimaryActions(ItemBridgeAdapter.ViewHolder vh) { 195aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout if (vh == null && getVerticalGridView() != null) { 196aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout vh = (ItemBridgeAdapter.ViewHolder) getVerticalGridView().findViewHolderForPosition(0); 1971e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout } 198aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout if (vh == null) { 199aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout mResetControlsToPrimaryActionsPending = true; 200aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout } else if (vh.getPresenter() instanceof PlaybackControlsRowPresenter) { 201aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout mResetControlsToPrimaryActionsPending = false; 202aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout ((PlaybackControlsRowPresenter) vh.getPresenter()).showPrimaryActions( 203aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout (PlaybackControlsRowPresenter.ViewHolder) vh.getViewHolder()); 204b682c5a20aa0a383ea2b3e7d639e51b3e7771bcdCraig Stout vh.getViewHolder().view.clearFocus(); 205d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout } 206d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout } 207d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout 208372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout /** 209372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout * Enables or disables view fading. If enabled, 210372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout * the view will be faded in when the fragment starts, 211372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout * and will fade out after a time period. The timeout 212372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout * period is reset each time {@link #tickle} is called. 213372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout * 214372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout */ 215372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout public void setFadingEnabled(boolean enabled) { 216372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout if (DEBUG) Log.v(TAG, "setFadingEnabled " + enabled); 217372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout if (enabled != mFadingEnabled) { 218372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout mFadingEnabled = enabled; 219f47fb1e34efd538c322f7539893272ba847cdbdcCraig Stout if (mFadingEnabled) { 220f47fb1e34efd538c322f7539893272ba847cdbdcCraig Stout if (isResumed() && mFadingStatus == IDLE 221f47fb1e34efd538c322f7539893272ba847cdbdcCraig Stout && !mHandler.hasMessages(START_FADE_OUT)) { 222f47fb1e34efd538c322f7539893272ba847cdbdcCraig Stout startFadeTimer(); 223372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout } 224f47fb1e34efd538c322f7539893272ba847cdbdcCraig Stout } else { 225f47fb1e34efd538c322f7539893272ba847cdbdcCraig Stout // Ensure fully opaque 226f47fb1e34efd538c322f7539893272ba847cdbdcCraig Stout mHandler.removeMessages(START_FADE_OUT); 227f47fb1e34efd538c322f7539893272ba847cdbdcCraig Stout fade(true); 228372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout } 229372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout } 230372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout } 231372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout 232372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout /** 233372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout * Returns true if view fading is enabled. 234372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout */ 235372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout public boolean isFadingEnabled() { 236372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout return mFadingEnabled; 237372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout } 238372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout 239372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout /** 240372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout * Sets the listener to be called when fade in or out has completed. 241372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout */ 242372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout public void setFadeCompleteListener(OnFadeCompleteListener listener) { 243372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout mFadeCompleteListener = listener; 244372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout } 245372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout 246372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout /** 247372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout * Returns the listener to be called when fade in or out has completed. 248372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout */ 249372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout public OnFadeCompleteListener getFadeCompleteListener() { 250372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout return mFadeCompleteListener; 251372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout } 252372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout 253372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout /** 254eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout * Sets the input event handler. 255eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout */ 256eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout public final void setInputEventHandler(InputEventHandler handler) { 257eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout mInputEventHandler = handler; 258eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout } 259eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout 260eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout /** 261eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout * Returns the input event handler. 262eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout */ 2632dfed05c8ab53ca7c28424c9c03b1a87b9b7ca0dCraig Stout public final InputEventHandler getInputEventHandler() { 264eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout return mInputEventHandler; 265eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout } 266eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout 267eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout /** 268372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout * Tickles the playback controls. Fades in the view if it was faded out, 269372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout * otherwise resets the fade out timer. Tickling on input events is handled 270372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout * by the fragment. 271372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout */ 272372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout public void tickle() { 273372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout if (DEBUG) Log.v(TAG, "tickle enabled " + mFadingEnabled + " isResumed " + isResumed()); 274372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout if (!mFadingEnabled || !isResumed()) { 275372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout return; 276372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout } 277372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout if (mHandler.hasMessages(START_FADE_OUT)) { 278372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout // Restart the timer 279372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout startFadeTimer(); 280372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout } else { 281372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout fade(true); 282372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout } 283372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout } 284372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout 28560bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout private boolean areControlsHidden() { 28660bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout return mFadingStatus == IDLE && mBgAlpha == 0; 287cbfc318baee2fc054af4c723bfac0fd3c28a1667Craig Stout } 288cbfc318baee2fc054af4c723bfac0fd3c28a1667Craig Stout 289cbfc318baee2fc054af4c723bfac0fd3c28a1667Craig Stout private boolean onInterceptInputEvent(InputEvent event) { 29060bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout final boolean controlsHidden = areControlsHidden(); 29160bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout if (DEBUG) Log.v(TAG, "onInterceptInputEvent hidden " + controlsHidden + " " + event); 29260bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout boolean consumeEvent = false; 293c92c356de1a687598a031f3452053dc6c9af9b77Craig Stout int keyCode = KeyEvent.KEYCODE_UNKNOWN; 294c92c356de1a687598a031f3452053dc6c9af9b77Craig Stout 29560bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout if (mInputEventHandler != null) { 29660bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout consumeEvent = mInputEventHandler.handleInputEvent(event); 29760bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout } 298cbfc318baee2fc054af4c723bfac0fd3c28a1667Craig Stout if (event instanceof KeyEvent) { 299c92c356de1a687598a031f3452053dc6c9af9b77Craig Stout keyCode = ((KeyEvent) event).getKeyCode(); 300c92c356de1a687598a031f3452053dc6c9af9b77Craig Stout } 30160bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout 30260bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout switch (keyCode) { 30360bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout case KeyEvent.KEYCODE_DPAD_CENTER: 30460bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout case KeyEvent.KEYCODE_DPAD_DOWN: 30560bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout case KeyEvent.KEYCODE_DPAD_UP: 30660bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout case KeyEvent.KEYCODE_DPAD_LEFT: 30760bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout case KeyEvent.KEYCODE_DPAD_RIGHT: 30860bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout // Event may be consumed; regardless, if controls are hidden then these keys will 30960bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout // bring up the controls. 31060bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout if (controlsHidden) { 31160bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout consumeEvent = true; 31260bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout } 313cbfc318baee2fc054af4c723bfac0fd3c28a1667Craig Stout tickle(); 31460bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout break; 31560bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout case KeyEvent.KEYCODE_BACK: 31660bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout // If fading enabled and controls are not hidden, back will be consumed to fade 31760bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout // them out (even if the key was consumed by the handler). 31860bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout if (mFadingEnabled && !controlsHidden) { 31960bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout consumeEvent = true; 32060bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout mHandler.removeMessages(START_FADE_OUT); 32160bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout fade(false); 32260bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout } else if (consumeEvent) { 32360bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout tickle(); 32460bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout } 32560bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout break; 32660bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout default: 32760bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout if (consumeEvent) { 32860bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout tickle(); 32960bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout } 330eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout } 331372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout return consumeEvent; 332372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout } 333372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout 334372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout @Override 335372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout public void onResume() { 336372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout super.onResume(); 337372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout if (mFadingEnabled) { 338d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout setBgAlpha(0); 339372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout fade(true); 340372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout } 341372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout getVerticalGridView().setOnTouchInterceptListener(mOnTouchInterceptListener); 342372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout getVerticalGridView().setOnKeyInterceptListener(mOnKeyInterceptListener); 343372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout } 344372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout 345372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout private void startFadeTimer() { 3461e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout if (mHandler != null) { 3471e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout mHandler.removeMessages(START_FADE_OUT); 3481e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout mHandler.sendEmptyMessageDelayed(START_FADE_OUT, mShowTimeMs); 3491e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout } 350372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout } 351372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout 352d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout private static ValueAnimator loadAnimator(Context context, int resId) { 353d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout ValueAnimator animator = (ValueAnimator) AnimatorInflater.loadAnimator(context, resId); 354d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout animator.setDuration(animator.getDuration() * ANIMATION_MULTIPLIER); 355d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout return animator; 356d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout } 357d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout 358d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout private void loadBgAnimator() { 359d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout AnimatorUpdateListener listener = new AnimatorUpdateListener() { 360d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout @Override 361d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout public void onAnimationUpdate(ValueAnimator arg0) { 362d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout setBgAlpha((Integer) arg0.getAnimatedValue()); 363d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout } 364d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout }; 365d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout 366d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout mBgFadeInAnimator = loadAnimator(getActivity(), R.animator.lb_playback_bg_fade_in); 367d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout mBgFadeInAnimator.addUpdateListener(listener); 368d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout mBgFadeInAnimator.addListener(mFadeListener); 369d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout 370d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout mBgFadeOutAnimator = loadAnimator(getActivity(), R.animator.lb_playback_bg_fade_out); 371d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout mBgFadeOutAnimator.addUpdateListener(listener); 372d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout mBgFadeOutAnimator.addListener(mFadeListener); 373d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout } 374d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout 375d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout private TimeInterpolator mLogDecelerateInterpolator = new LogDecelerateInterpolator(100,0); 376d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout private TimeInterpolator mLogAccelerateInterpolator = new LogAccelerateInterpolator(100,0); 377d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout 3782d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout private View getControlRowView() { 3792d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout if (getVerticalGridView() == null) { 3802d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout return null; 3812d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout } 3822d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout RecyclerView.ViewHolder vh = getVerticalGridView().findViewHolderForPosition(0); 3832d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout if (vh == null) { 3842d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout return null; 3852d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout } 3862d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout return vh.itemView; 3872d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout } 3882d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout 389d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout private void loadControlRowAnimator() { 3902d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout final AnimatorListener listener = new AnimatorListener() { 391d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout @Override 3922d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout void getViews(ArrayList<View> views) { 3932d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout View view = getControlRowView(); 3942d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout if (view != null) { 3952d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout views.add(view); 3961e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout } 3972d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout } 3982d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout }; 3992d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout final AnimatorUpdateListener updateListener = new AnimatorUpdateListener() { 4002d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout @Override 4012d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout public void onAnimationUpdate(ValueAnimator arg0) { 4022d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout View view = getControlRowView(); 4032d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout if (view != null) { 404d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout final float fraction = (Float) arg0.getAnimatedValue(); 405d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout if (DEBUG) Log.v(TAG, "fraction " + fraction); 4062d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout view.setAlpha(fraction); 4072d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout view.setTranslationY((float) mAnimationTranslateY * (1f - fraction)); 408d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout } 409d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout } 410d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout }; 411d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout 412d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout mControlRowFadeInAnimator = loadAnimator( 413d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout getActivity(), R.animator.lb_playback_controls_fade_in); 4142d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout mControlRowFadeInAnimator.addUpdateListener(updateListener); 4152d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout mControlRowFadeInAnimator.addListener(listener); 416d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout mControlRowFadeInAnimator.setInterpolator(mLogDecelerateInterpolator); 417d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout 418d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout mControlRowFadeOutAnimator = loadAnimator( 419d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout getActivity(), R.animator.lb_playback_controls_fade_out); 4202d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout mControlRowFadeOutAnimator.addUpdateListener(updateListener); 4212d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout mControlRowFadeOutAnimator.addListener(listener); 422d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout mControlRowFadeOutAnimator.setInterpolator(mLogAccelerateInterpolator); 423d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout } 424d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout 425d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout private void loadOtherRowAnimator() { 4262d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout final AnimatorListener listener = new AnimatorListener() { 427d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout @Override 4282d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout void getViews(ArrayList<View> views) { 4291e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout if (getVerticalGridView() == null) { 4301e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout return; 4311e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout } 432d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout final int count = getVerticalGridView().getChildCount(); 433d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout for (int i = 0; i < count; i++) { 434d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout View view = getVerticalGridView().getChildAt(i); 4352d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout if (view != null) { 4362d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout views.add(view); 4372d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout } 4382d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout } 4392d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout } 4402d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout }; 4412d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout final AnimatorUpdateListener updateListener = new AnimatorUpdateListener() { 4422d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout @Override 4432d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout public void onAnimationUpdate(ValueAnimator arg0) { 4441df1f18de496764a0c922053e601d1b6d6d3f31cCraig Stout if (getVerticalGridView() == null) { 4451df1f18de496764a0c922053e601d1b6d6d3f31cCraig Stout return; 4461df1f18de496764a0c922053e601d1b6d6d3f31cCraig Stout } 4472d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout final float fraction = (Float) arg0.getAnimatedValue(); 4482d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout for (View view : listener.mViews) { 449d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout if (getVerticalGridView().getChildPosition(view) > 0) { 450d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout view.setAlpha(fraction); 4516b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout view.setTranslationY((float) mAnimationTranslateY * (1f - fraction)); 452d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout } 453d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout } 454d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout } 455d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout }; 456d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout 457d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout mOtherRowFadeInAnimator = loadAnimator( 458d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout getActivity(), R.animator.lb_playback_controls_fade_in); 4592d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout mOtherRowFadeInAnimator.addListener(listener); 4602d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout mOtherRowFadeInAnimator.addUpdateListener(updateListener); 461d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout mOtherRowFadeInAnimator.setInterpolator(mLogDecelerateInterpolator); 462d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout 463d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout mOtherRowFadeOutAnimator = loadAnimator( 464d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout getActivity(), R.animator.lb_playback_controls_fade_out); 4652d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout mOtherRowFadeOutAnimator.addListener(listener); 4662d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout mOtherRowFadeOutAnimator.addUpdateListener(updateListener); 4676b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout mOtherRowFadeOutAnimator.setInterpolator(new AccelerateInterpolator()); 4686b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout } 4696b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout 4706b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout private void loadDescriptionAnimator() { 4716b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout AnimatorUpdateListener listener = new AnimatorUpdateListener() { 4726b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout @Override 4736b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout public void onAnimationUpdate(ValueAnimator arg0) { 4746b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout if (getVerticalGridView() == null) { 4756b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout return; 4766b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout } 4776b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout ItemBridgeAdapter.ViewHolder adapterVh = (ItemBridgeAdapter.ViewHolder) 4786b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout getVerticalGridView().findViewHolderForPosition(0); 4796b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout if (adapterVh != null && adapterVh.getViewHolder() 4806b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout instanceof PlaybackControlsRowPresenter.ViewHolder) { 4816b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout final Presenter.ViewHolder vh = ((PlaybackControlsRowPresenter.ViewHolder) 4826b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout adapterVh.getViewHolder()).mDescriptionViewHolder; 4838f5c183ba7b9df6b5339586f51219b4d5e6305f3Craig Stout if (vh != null) { 4848f5c183ba7b9df6b5339586f51219b4d5e6305f3Craig Stout vh.view.setAlpha((Float) arg0.getAnimatedValue()); 4858f5c183ba7b9df6b5339586f51219b4d5e6305f3Craig Stout } 4866b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout } 4876b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout } 4886b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout }; 4896b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout 4906b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout mDescriptionFadeInAnimator = loadAnimator( 4916b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout getActivity(), R.animator.lb_playback_description_fade_in); 4926b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout mDescriptionFadeInAnimator.addUpdateListener(listener); 4936b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout mDescriptionFadeInAnimator.setInterpolator(mLogDecelerateInterpolator); 4946b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout 4956b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout mDescriptionFadeOutAnimator = loadAnimator( 4966b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout getActivity(), R.animator.lb_playback_description_fade_out); 4976b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout mDescriptionFadeOutAnimator.addUpdateListener(listener); 498d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout } 499d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout 500372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout private void fade(boolean fadeIn) { 501372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout if (DEBUG) Log.v(TAG, "fade " + fadeIn); 502372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout if (getView() == null) { 503372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout return; 504372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout } 505372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout if ((fadeIn && mFadingStatus == IN) || (!fadeIn && mFadingStatus == OUT)) { 506d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout if (DEBUG) Log.v(TAG, "requested fade in progress"); 507d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout return; 508d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout } 509d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout if ((fadeIn && mBgAlpha == 255) || (!fadeIn && mBgAlpha == 0)) { 510d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout if (DEBUG) Log.v(TAG, "fade is no-op"); 511372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout return; 512372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout } 513372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout 5146b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout mAnimationTranslateY = getVerticalGridView().getSelectedPosition() == 0 ? 5156b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout mMajorFadeTranslateY : mMinorFadeTranslateY; 516d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout 517d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout if (mFadingStatus == IDLE) { 518d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout if (fadeIn) { 519d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout mBgFadeInAnimator.start(); 520d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout mControlRowFadeInAnimator.start(); 521d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout mOtherRowFadeInAnimator.start(); 5226b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout mDescriptionFadeInAnimator.start(); 523d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout } else { 524d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout mBgFadeOutAnimator.start(); 525d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout mControlRowFadeOutAnimator.start(); 526d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout mOtherRowFadeOutAnimator.start(); 5276b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout mDescriptionFadeOutAnimator.start(); 528d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout } 529d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout } else { 530d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout if (fadeIn) { 531d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout mBgFadeOutAnimator.reverse(); 532d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout mControlRowFadeOutAnimator.reverse(); 533d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout mOtherRowFadeOutAnimator.reverse(); 5346b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout mDescriptionFadeOutAnimator.reverse(); 535d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout } else { 536d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout mBgFadeInAnimator.reverse(); 537d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout mControlRowFadeInAnimator.reverse(); 538d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout mOtherRowFadeInAnimator.reverse(); 5396b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout mDescriptionFadeInAnimator.reverse(); 540d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout } 541d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout } 542d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout 543d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout // If fading in while control row is focused, set initial translationY so 544d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout // views slide in from below. 5456b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout if (fadeIn && mFadingStatus == IDLE) { 546d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout final int count = getVerticalGridView().getChildCount(); 547d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout for (int i = 0; i < count; i++) { 5486b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout getVerticalGridView().getChildAt(i).setTranslationY(mAnimationTranslateY); 549d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout } 550d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout } 551d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout 552372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout mFadingStatus = fadeIn ? IN : OUT; 553372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout } 5547ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout 5557ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout /** 5567ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout * Sets the list of rows for the fragment. 5577ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout */ 5587ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout @Override 5597ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout public void setAdapter(ObjectAdapter adapter) { 5606dca725412977bb56b933bdec120e31909233cdbCraig Stout if (getAdapter() != null) { 5616dca725412977bb56b933bdec120e31909233cdbCraig Stout getAdapter().unregisterObserver(mObserver); 5626dca725412977bb56b933bdec120e31909233cdbCraig Stout } 5637ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout super.setAdapter(adapter); 5646dca725412977bb56b933bdec120e31909233cdbCraig Stout if (adapter != null) { 5656dca725412977bb56b933bdec120e31909233cdbCraig Stout adapter.registerObserver(mObserver); 5666dca725412977bb56b933bdec120e31909233cdbCraig Stout } 5677ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout } 5687ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout 5697ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout @Override 5707ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout void setVerticalGridViewLayout(VerticalGridView listview) { 571d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout if (listview == null) { 5727ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout return; 5737ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout } 574d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout // Padding affects alignment when last row is focused 575d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout // (last is first when there's only one row). 576d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout setBottomPadding(listview, mPaddingBottom); 577d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout 578d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout // Item alignment affects focused row that isn't the last. 579d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout listview.setItemAlignmentOffset(mAlignPosition); 5807ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout listview.setItemAlignmentOffsetPercent(100); 581d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout 582d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout // Push rows to the bottom. 5837ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout listview.setWindowAlignmentOffset(0); 5847ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout listview.setWindowAlignmentOffsetPercent(100); 5857ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout listview.setWindowAlignment(VerticalGridView.WINDOW_ALIGN_HIGH_EDGE); 5867ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout } 5877ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout 588d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout private static void setBottomPadding(View view, int padding) { 589d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout view.setPadding(view.getPaddingLeft(), view.getPaddingTop(), 590d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout view.getPaddingRight(), padding); 591d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout } 592d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout 5937ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout @Override 5947ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout public void onCreate(Bundle savedInstanceState) { 5957ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout super.onCreate(savedInstanceState); 5967ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout 5977ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout mAlignPosition = 598d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout getResources().getDimensionPixelSize(R.dimen.lb_playback_controls_align_bottom); 599d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout mPaddingBottom = 600d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout getResources().getDimensionPixelSize(R.dimen.lb_playback_controls_padding_bottom); 6017709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout mBgDarkColor = 6027709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout getResources().getColor(R.color.lb_playback_controls_background_dark); 6037709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout mBgLightColor = 6047709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout getResources().getColor(R.color.lb_playback_controls_background_light); 605372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout mShowTimeMs = 606372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout getResources().getInteger(R.integer.lb_playback_controls_show_time_ms); 6076b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout mMajorFadeTranslateY = 6086b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout getResources().getDimensionPixelSize(R.dimen.lb_playback_major_fade_translate_y); 6096b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout mMinorFadeTranslateY = 6106b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout getResources().getDimensionPixelSize(R.dimen.lb_playback_minor_fade_translate_y); 611d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout 612d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout loadBgAnimator(); 613d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout loadControlRowAnimator(); 614d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout loadOtherRowAnimator(); 6156b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout loadDescriptionAnimator(); 6167709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout } 6177709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout 6187709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout /** 6197709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout * Sets the background type. 6207709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout * 6217709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout * @param type One of BG_LIGHT, BG_DARK, or BG_NONE. 6227709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout */ 6237709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout public void setBackgroundType(int type) { 624372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout switch (type) { 625372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout case BG_LIGHT: 626372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout case BG_DARK: 627372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout case BG_NONE: 628372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout if (type != mBackgroundType) { 629372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout mBackgroundType = type; 630372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout updateBackground(); 631372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout } 632372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout break; 633372d07bb41510d91a6a662a1906aceb0ee759481Craig Stout default: 6347709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout throw new IllegalArgumentException("Invalid background type"); 6357709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout } 6367709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout } 6377709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout 6387709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout /** 6397709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout * Returns the background type. 6407709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout */ 6417709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout public int getBackgroundType() { 6427709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout return mBackgroundType; 6437709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout } 6447709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout 6457709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout private void updateBackground() { 6467709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout if (mRootView != null) { 6477709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout int color = mBgDarkColor; 6487709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout switch (mBackgroundType) { 6497709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout case BG_DARK: break; 6507709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout case BG_LIGHT: color = mBgLightColor; break; 6517709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout case BG_NONE: color = Color.TRANSPARENT; break; 6527709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout } 6537709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout mRootView.setBackground(new ColorDrawable(color)); 6547709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout } 6557709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout } 6567709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout 657d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout private void updateControlsBottomSpace(ItemBridgeAdapter.ViewHolder vh) { 658d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout // Add extra space between rows 0 and 1 659d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout if (vh == null && getVerticalGridView() != null) { 660d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout vh = (ItemBridgeAdapter.ViewHolder) 661d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout getVerticalGridView().findViewHolderForPosition(0); 662d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout } 663d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout if (vh != null && vh.getPresenter() instanceof PlaybackControlsRowPresenter) { 664d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout final int adapterSize = getAdapter() == null ? 0 : getAdapter().size(); 665d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout ((PlaybackControlsRowPresenter) vh.getPresenter()).showBottomSpace( 666d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout (PlaybackControlsRowPresenter.ViewHolder) vh.getViewHolder(), 667d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout adapterSize > 1); 668d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout } 669d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout } 670d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout 671d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout private final ItemBridgeAdapter.AdapterListener mAdapterListener = 672d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout new ItemBridgeAdapter.AdapterListener() { 673d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout @Override 674d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout public void onAttachedToWindow(ItemBridgeAdapter.ViewHolder vh) { 675d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout if (DEBUG) Log.v(TAG, "onAttachedToWindow " + vh.getViewHolder().view); 676d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout if ((mFadingStatus == IDLE && mBgAlpha == 0) || mFadingStatus == OUT) { 677d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout if (DEBUG) Log.v(TAG, "setting alpha to 0"); 678d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout vh.getViewHolder().view.setAlpha(0); 679d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout } 680aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout if (vh.getPosition() == 0 && mResetControlsToPrimaryActionsPending) { 681aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout resetControlsToPrimaryActions(vh); 682aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout } 683d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout } 684d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout @Override 685d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout public void onDetachedFromWindow(ItemBridgeAdapter.ViewHolder vh) { 686d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout if (DEBUG) Log.v(TAG, "onDetachedFromWindow " + vh.getViewHolder().view); 687d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout // Reset animation state 688d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout vh.getViewHolder().view.setAlpha(1f); 689d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout vh.getViewHolder().view.setTranslationY(0); 6906b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout if (vh.getViewHolder() instanceof PlaybackControlsRowPresenter.ViewHolder) { 6918f5c183ba7b9df6b5339586f51219b4d5e6305f3Craig Stout Presenter.ViewHolder descriptionVh = ((PlaybackControlsRowPresenter.ViewHolder) 6928f5c183ba7b9df6b5339586f51219b4d5e6305f3Craig Stout vh.getViewHolder()).mDescriptionViewHolder; 6938f5c183ba7b9df6b5339586f51219b4d5e6305f3Craig Stout if (descriptionVh != null) { 6948f5c183ba7b9df6b5339586f51219b4d5e6305f3Craig Stout descriptionVh.view.setAlpha(1f); 6958f5c183ba7b9df6b5339586f51219b4d5e6305f3Craig Stout } 6966b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout } 697d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout } 698d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout @Override 699d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout public void onBind(ItemBridgeAdapter.ViewHolder vh) { 700d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout if (vh.getPosition() == 0) { 701d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout updateControlsBottomSpace(vh); 702d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout } 703d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout } 704d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout }; 705d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout 7067709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout @Override 7077709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout public View onCreateView(LayoutInflater inflater, ViewGroup container, 7087709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout Bundle savedInstanceState) { 7097709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout mRootView = super.onCreateView(inflater, container, savedInstanceState); 710d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout mBgAlpha = 255; 7117709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout updateBackground(); 712d1adbdcb44a48e142d28a93189c57edfe62d93ceCraig Stout getRowsFragment().setExternalAdapterListener(mAdapterListener); 7137709709c2c78490a21311e9950d5dca7e89a6aedCraig Stout return mRootView; 7147ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout } 7156dca725412977bb56b933bdec120e31909233cdbCraig Stout 7161e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout @Override 7171e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout public void onDestroyView() { 7181e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout mRootView = null; 7191e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout super.onDestroyView(); 7201e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout } 7211e5725d52c7ec12b184dcfce6bfafa80aed35230Craig Stout 7226dca725412977bb56b933bdec120e31909233cdbCraig Stout private final DataObserver mObserver = new DataObserver() { 7236dca725412977bb56b933bdec120e31909233cdbCraig Stout public void onChanged() { 724d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout updateControlsBottomSpace(null); 7256dca725412977bb56b933bdec120e31909233cdbCraig Stout } 7266dca725412977bb56b933bdec120e31909233cdbCraig Stout }; 7272d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout 7282d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout static abstract class AnimatorListener implements Animator.AnimatorListener { 7292d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout ArrayList<View> mViews = new ArrayList<View>(); 7302d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout ArrayList<Integer> mLayerType = new ArrayList<Integer>(); 7312d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout 7322d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout public void onAnimationCancel(Animator animation) { 7332d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout } 7342d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout public void onAnimationRepeat(Animator animation) { 7352d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout } 7362d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout public void onAnimationStart(Animator animation) { 7372d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout getViews(mViews); 7382d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout for (View view : mViews) { 7392d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout mLayerType.add(view.getLayerType()); 7402d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout view.setLayerType(View.LAYER_TYPE_HARDWARE, null); 7412d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout } 7422d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout } 7432d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout public void onAnimationEnd(Animator animation) { 7442d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout for (int i = 0; i < mViews.size(); i++) { 7452d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout mViews.get(i).setLayerType(mLayerType.get(i), null); 7462d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout } 7472d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout mLayerType.clear(); 7482d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout mViews.clear(); 7492d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout } 7502d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout abstract void getViews(ArrayList<View> views); 7512d33e3cfedc56adc2d4e5ac6279ec683d041fe21Craig Stout }; 7527ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout} 753