16193c12a1897723c87b41f4e304a8cd04deef2dcDake Gu/* This file is auto-generated from PlaybackOverlayFragment.java. DO NOT MODIFY. */ 26193c12a1897723c87b41f4e304a8cd04deef2dcDake Gu 361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu/* 461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Copyright (C) 2014 The Android Open Source Project 561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * 661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * in compliance with the License. You may obtain a copy of the License at 861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * 961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * http://www.apache.org/licenses/LICENSE-2.0 1061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * 1161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Unless required by applicable law or agreed to in writing, software distributed under the License 1261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 1361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * or implied. See the License for the specific language governing permissions and limitations under 1461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * the License. 1561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 1661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gupackage android.support.v17.leanback.app; 1761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 1861905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.graphics.Color; 1961905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.graphics.drawable.ColorDrawable; 2061905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.animation.Animator; 2161905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.animation.AnimatorInflater; 2261905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.animation.TimeInterpolator; 2361905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.animation.ValueAnimator; 2460bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stoutimport android.support.v17.leanback.widget.Action; 2560bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stoutimport android.support.v17.leanback.widget.PlaybackControlsRow; 2660bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stoutimport android.support.v17.leanback.widget.Row; 27cbfc318baee2fc054af4c723bfac0fd3c28a1667Craig Stoutimport android.view.InputEvent; 2861905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.view.animation.AccelerateInterpolator; 2961905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.animation.ValueAnimator.AnimatorUpdateListener; 3061905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.content.Context; 3161905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.os.Bundle; 3261905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.os.Handler; 3361905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.os.Message; 3461905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.support.v7.widget.RecyclerView; 3561905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.support.v17.leanback.R; 3661905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.support.v17.leanback.animation.LogAccelerateInterpolator; 3761905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.support.v17.leanback.animation.LogDecelerateInterpolator; 3861905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.support.v17.leanback.widget.Presenter; 3961905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.support.v17.leanback.widget.ItemBridgeAdapter; 4061905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.support.v17.leanback.widget.ObjectAdapter; 4161905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.support.v17.leanback.widget.ObjectAdapter.DataObserver; 4261905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.support.v17.leanback.widget.VerticalGridView; 4361905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.support.v17.leanback.widget.PlaybackControlsRowPresenter; 4461905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.util.Log; 4561905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.view.KeyEvent; 4661905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.view.LayoutInflater; 4761905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.view.MotionEvent; 4861905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.view.View; 4961905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport android.view.ViewGroup; 5061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 5161905b0b52c50018dcaebcd79699c39b8f28d622Dake Guimport java.util.ArrayList; 5261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 5361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu/** 5461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * A fragment for displaying playback controls and related content. 55a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * <p> 56a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * A PlaybackOverlaySupportFragment renders the elements of its {@link ObjectAdapter} as a set 57a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * of rows in a vertical list. The elements in this adapter must be subclasses 58a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * of {@link Row}. 59a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * </p> 60a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * <p> 61a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * An instance of {@link android.support.v17.leanback.widget.PlaybackControlsRow} is expected to be 6261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * at position 0 in the adapter. 63a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * </p> 6461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 6561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gupublic class PlaybackOverlaySupportFragment extends DetailsSupportFragment { 6661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 6761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 6861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * No background. 6961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 7061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public static final int BG_NONE = 0; 7161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 7261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 7361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * A dark translucent background. 7461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 7561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public static final int BG_DARK = 1; 7661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 7761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 7861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * A light translucent background. 7961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 8061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public static final int BG_LIGHT = 2; 8161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 82a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout /** 83a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * Listener allowing the application to receive notification of fade in and/or fade out 84a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * completion events. 85a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout */ 8661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public static class OnFadeCompleteListener { 8761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void onFadeInComplete() { 8861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 8961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void onFadeOutComplete() { 9061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 9161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 9261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 93a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout /** 94a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * Interface allowing the application to handle input events. 95a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout */ 96eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout public interface InputEventHandler { 97eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout /** 98eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout * Called when an {@link InputEvent} is received. 99eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout * 100eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout * @return If the event should be consumed, return true. To allow the event to 101eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout * continue on to the next handler, return false. 102eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout */ 103eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout public boolean handleInputEvent(InputEvent event); 104eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout } 105eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout 10661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private static final String TAG = "PlaybackOverlaySupportFragment"; 10761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private static final boolean DEBUG = false; 10861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private static final int ANIMATION_MULTIPLIER = 1; 10961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 11061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private static int START_FADE_OUT = 1; 11161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 11261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu // Fading status 11361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private static final int IDLE = 0; 11461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private static final int IN = 1; 11561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private static final int OUT = 2; 11661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 11761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private int mAlignPosition; 11861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private int mPaddingBottom; 11961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private View mRootView; 12061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private int mBackgroundType = BG_DARK; 12161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private int mBgDarkColor; 12261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private int mBgLightColor; 12361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private int mShowTimeMs; 12461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private int mMajorFadeTranslateY, mMinorFadeTranslateY; 12561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private int mAnimationTranslateY; 12661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private OnFadeCompleteListener mFadeCompleteListener; 127eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout private InputEventHandler mInputEventHandler; 12861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private boolean mFadingEnabled = true; 12961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private int mFadingStatus = IDLE; 13061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private int mBgAlpha; 13161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private ValueAnimator mBgFadeInAnimator, mBgFadeOutAnimator; 13261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private ValueAnimator mControlRowFadeInAnimator, mControlRowFadeOutAnimator; 13361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private ValueAnimator mDescriptionFadeInAnimator, mDescriptionFadeOutAnimator; 13461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private ValueAnimator mOtherRowFadeInAnimator, mOtherRowFadeOutAnimator; 13561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private boolean mTranslateAnimationEnabled; 13661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private boolean mResetControlsToPrimaryActionsPending; 13761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private RecyclerView.ItemAnimator mItemAnimator; 13861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 13961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private final Animator.AnimatorListener mFadeListener = 14061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu new Animator.AnimatorListener() { 14161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 14261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void onAnimationStart(Animator animation) { 14361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu enableVerticalGridAnimations(false); 14461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 14561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 14661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void onAnimationRepeat(Animator animation) { 14761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 14861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 14961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void onAnimationCancel(Animator animation) { 15061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 15161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 15261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void onAnimationEnd(Animator animation) { 15361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (DEBUG) Log.v(TAG, "onAnimationEnd " + mBgAlpha); 15461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mBgAlpha > 0) { 15561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu enableVerticalGridAnimations(true); 15661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu startFadeTimer(); 15761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mFadeCompleteListener != null) { 15861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mFadeCompleteListener.onFadeInComplete(); 15961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 16061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } else { 16161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (getVerticalGridView() != null) { 16261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu // Reset focus to the controls row 16361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu getVerticalGridView().setSelectedPosition(0); 16461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu resetControlsToPrimaryActions(null); 16561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 16661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mFadeCompleteListener != null) { 16761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mFadeCompleteListener.onFadeOutComplete(); 16861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 16961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 17061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mFadingStatus = IDLE; 17161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 17261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu }; 17361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 17461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private final Handler mHandler = new Handler() { 17561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 17661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void handleMessage(Message message) { 17761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (message.what == START_FADE_OUT && mFadingEnabled) { 17861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu fade(false); 17961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 18061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 18161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu }; 18261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 18361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private final VerticalGridView.OnTouchInterceptListener mOnTouchInterceptListener = 18461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu new VerticalGridView.OnTouchInterceptListener() { 18561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public boolean onInterceptTouchEvent(MotionEvent event) { 186cbfc318baee2fc054af4c723bfac0fd3c28a1667Craig Stout return onInterceptInputEvent(event); 18761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 18861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu }; 18961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 19061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private final VerticalGridView.OnKeyInterceptListener mOnKeyInterceptListener = 19161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu new VerticalGridView.OnKeyInterceptListener() { 19261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public boolean onInterceptKeyEvent(KeyEvent event) { 193cbfc318baee2fc054af4c723bfac0fd3c28a1667Craig Stout return onInterceptInputEvent(event); 19461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 19561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu }; 19661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 19761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private void setBgAlpha(int alpha) { 19861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mBgAlpha = alpha; 19961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mRootView != null) { 20061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mRootView.getBackground().setAlpha(alpha); 20161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 20261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 20361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 20461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private void enableVerticalGridAnimations(boolean enable) { 20561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (getVerticalGridView() != null) { 20661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu getVerticalGridView().setAnimateChildLayout(enable); 20761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 20861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 20961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 21061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private void resetControlsToPrimaryActions(ItemBridgeAdapter.ViewHolder vh) { 21161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (vh == null && getVerticalGridView() != null) { 21261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu vh = (ItemBridgeAdapter.ViewHolder) getVerticalGridView().findViewHolderForPosition(0); 21361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 21461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (vh == null) { 21561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mResetControlsToPrimaryActionsPending = true; 21661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } else if (vh.getPresenter() instanceof PlaybackControlsRowPresenter) { 21761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mResetControlsToPrimaryActionsPending = false; 21861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu ((PlaybackControlsRowPresenter) vh.getPresenter()).showPrimaryActions( 21961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu (PlaybackControlsRowPresenter.ViewHolder) vh.getViewHolder()); 22061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 22161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 22261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 22361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 22461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Enables or disables view fading. If enabled, 22561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * the view will be faded in when the fragment starts, 22661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * and will fade out after a time period. The timeout 22761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * period is reset each time {@link #tickle} is called. 22861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * 22961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 23061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void setFadingEnabled(boolean enabled) { 23161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (DEBUG) Log.v(TAG, "setFadingEnabled " + enabled); 23261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (enabled != mFadingEnabled) { 23361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mFadingEnabled = enabled; 234f47fb1e34efd538c322f7539893272ba847cdbdcCraig Stout if (mFadingEnabled) { 235f47fb1e34efd538c322f7539893272ba847cdbdcCraig Stout if (isResumed() && mFadingStatus == IDLE 236f47fb1e34efd538c322f7539893272ba847cdbdcCraig Stout && !mHandler.hasMessages(START_FADE_OUT)) { 237f47fb1e34efd538c322f7539893272ba847cdbdcCraig Stout startFadeTimer(); 23861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 239f47fb1e34efd538c322f7539893272ba847cdbdcCraig Stout } else { 240f47fb1e34efd538c322f7539893272ba847cdbdcCraig Stout // Ensure fully opaque 241f47fb1e34efd538c322f7539893272ba847cdbdcCraig Stout mHandler.removeMessages(START_FADE_OUT); 242f47fb1e34efd538c322f7539893272ba847cdbdcCraig Stout fade(true); 24361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 24461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 24561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 24661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 24761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 24861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Returns true if view fading is enabled. 24961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 25061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public boolean isFadingEnabled() { 25161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return mFadingEnabled; 25261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 25361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 25461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 25561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Sets the listener to be called when fade in or out has completed. 25661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 25761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void setFadeCompleteListener(OnFadeCompleteListener listener) { 25861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mFadeCompleteListener = listener; 25961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 26061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 26161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 26261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Returns the listener to be called when fade in or out has completed. 26361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 26461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public OnFadeCompleteListener getFadeCompleteListener() { 26561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return mFadeCompleteListener; 26661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 26761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 26861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 269eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout * Sets the input event handler. 270eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout */ 271eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout public final void setInputEventHandler(InputEventHandler handler) { 272eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout mInputEventHandler = handler; 273eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout } 274eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout 275eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout /** 276eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout * Returns the input event handler. 277eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout */ 2782dfed05c8ab53ca7c28424c9c03b1a87b9b7ca0dCraig Stout public final InputEventHandler getInputEventHandler() { 279eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout return mInputEventHandler; 280eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout } 281eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout 282eb66dab544c4c1eabe4d469b7cea348d4b01e664Craig Stout /** 28361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Tickles the playback controls. Fades in the view if it was faded out, 28461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * otherwise resets the fade out timer. Tickling on input events is handled 28561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * by the fragment. 28661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 28761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void tickle() { 28861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (DEBUG) Log.v(TAG, "tickle enabled " + mFadingEnabled + " isResumed " + isResumed()); 28961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (!mFadingEnabled || !isResumed()) { 29061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return; 29161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 29261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mHandler.hasMessages(START_FADE_OUT)) { 29361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu // Restart the timer 29461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu startFadeTimer(); 29561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } else { 29661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu fade(true); 29761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 29861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 29961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 30060bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout private boolean areControlsHidden() { 30160bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout return mFadingStatus == IDLE && mBgAlpha == 0; 302cbfc318baee2fc054af4c723bfac0fd3c28a1667Craig Stout } 303cbfc318baee2fc054af4c723bfac0fd3c28a1667Craig Stout 304cbfc318baee2fc054af4c723bfac0fd3c28a1667Craig Stout private boolean onInterceptInputEvent(InputEvent event) { 30560bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout final boolean controlsHidden = areControlsHidden(); 30660bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout if (DEBUG) Log.v(TAG, "onInterceptInputEvent hidden " + controlsHidden + " " + event); 30760bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout boolean consumeEvent = false; 308c92c356de1a687598a031f3452053dc6c9af9b77Craig Stout int keyCode = KeyEvent.KEYCODE_UNKNOWN; 309c92c356de1a687598a031f3452053dc6c9af9b77Craig Stout 31060bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout if (mInputEventHandler != null) { 31160bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout consumeEvent = mInputEventHandler.handleInputEvent(event); 31260bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout } 313cbfc318baee2fc054af4c723bfac0fd3c28a1667Craig Stout if (event instanceof KeyEvent) { 314c92c356de1a687598a031f3452053dc6c9af9b77Craig Stout keyCode = ((KeyEvent) event).getKeyCode(); 315c92c356de1a687598a031f3452053dc6c9af9b77Craig Stout } 31660bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout 31760bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout switch (keyCode) { 31860bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout case KeyEvent.KEYCODE_DPAD_CENTER: 31960bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout case KeyEvent.KEYCODE_DPAD_DOWN: 32060bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout case KeyEvent.KEYCODE_DPAD_UP: 32160bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout case KeyEvent.KEYCODE_DPAD_LEFT: 32260bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout case KeyEvent.KEYCODE_DPAD_RIGHT: 32360bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout // Event may be consumed; regardless, if controls are hidden then these keys will 32460bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout // bring up the controls. 32560bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout if (controlsHidden) { 32660bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout consumeEvent = true; 32760bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout } 328cbfc318baee2fc054af4c723bfac0fd3c28a1667Craig Stout tickle(); 32960bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout break; 33060bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout case KeyEvent.KEYCODE_BACK: 331c89266e21f0269aecd5df2dc2a39f6f0cf11a58eCraig Stout case KeyEvent.KEYCODE_ESCAPE: 33260bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout // If fading enabled and controls are not hidden, back will be consumed to fade 33360bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout // them out (even if the key was consumed by the handler). 33460bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout if (mFadingEnabled && !controlsHidden) { 33560bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout consumeEvent = true; 33660bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout mHandler.removeMessages(START_FADE_OUT); 33760bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout fade(false); 33860bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout } else if (consumeEvent) { 33960bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout tickle(); 34060bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout } 34160bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout break; 34260bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout default: 34360bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout if (consumeEvent) { 34460bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout tickle(); 34560bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout } 346cbfc318baee2fc054af4c723bfac0fd3c28a1667Craig Stout } 34761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return consumeEvent; 34861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 34961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 35061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 35161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void onResume() { 35261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu super.onResume(); 35361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mFadingEnabled) { 35461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu setBgAlpha(0); 35561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu fade(true); 35661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 35761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu getVerticalGridView().setOnTouchInterceptListener(mOnTouchInterceptListener); 35861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu getVerticalGridView().setOnKeyInterceptListener(mOnKeyInterceptListener); 35961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 36061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 36161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private void startFadeTimer() { 36261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mHandler != null) { 36361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mHandler.removeMessages(START_FADE_OUT); 36461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mHandler.sendEmptyMessageDelayed(START_FADE_OUT, mShowTimeMs); 36561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 36661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 36761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 36861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private static ValueAnimator loadAnimator(Context context, int resId) { 36961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu ValueAnimator animator = (ValueAnimator) AnimatorInflater.loadAnimator(context, resId); 37061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu animator.setDuration(animator.getDuration() * ANIMATION_MULTIPLIER); 37161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return animator; 37261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 37361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 37461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private void loadBgAnimator() { 37561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu AnimatorUpdateListener listener = new AnimatorUpdateListener() { 37661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 37761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void onAnimationUpdate(ValueAnimator arg0) { 37861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu setBgAlpha((Integer) arg0.getAnimatedValue()); 37961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 38061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu }; 38161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 38261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mBgFadeInAnimator = loadAnimator(getActivity(), R.animator.lb_playback_bg_fade_in); 38361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mBgFadeInAnimator.addUpdateListener(listener); 38461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mBgFadeInAnimator.addListener(mFadeListener); 38561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 38661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mBgFadeOutAnimator = loadAnimator(getActivity(), R.animator.lb_playback_bg_fade_out); 38761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mBgFadeOutAnimator.addUpdateListener(listener); 38861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mBgFadeOutAnimator.addListener(mFadeListener); 38961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 39061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 39161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private TimeInterpolator mLogDecelerateInterpolator = new LogDecelerateInterpolator(100,0); 39261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private TimeInterpolator mLogAccelerateInterpolator = new LogAccelerateInterpolator(100,0); 39361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 39461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private View getControlRowView() { 39561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (getVerticalGridView() == null) { 39661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return null; 39761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 39861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu RecyclerView.ViewHolder vh = getVerticalGridView().findViewHolderForPosition(0); 39961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (vh == null) { 40061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return null; 40161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 40261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return vh.itemView; 40361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 40461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 40561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private void loadControlRowAnimator() { 40661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu final AnimatorListener listener = new AnimatorListener() { 40761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 40861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu void getViews(ArrayList<View> views) { 40961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu View view = getControlRowView(); 41061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (view != null) { 41161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu views.add(view); 41261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 41361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 41461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu }; 41561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu final AnimatorUpdateListener updateListener = new AnimatorUpdateListener() { 41661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 41761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void onAnimationUpdate(ValueAnimator arg0) { 41861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu View view = getControlRowView(); 41961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (view != null) { 42061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu final float fraction = (Float) arg0.getAnimatedValue(); 42161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (DEBUG) Log.v(TAG, "fraction " + fraction); 42261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu view.setAlpha(fraction); 42361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu view.setTranslationY((float) mAnimationTranslateY * (1f - fraction)); 42461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 42561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 42661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu }; 42761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 42861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mControlRowFadeInAnimator = loadAnimator( 42961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu getActivity(), R.animator.lb_playback_controls_fade_in); 43061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mControlRowFadeInAnimator.addUpdateListener(updateListener); 43161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mControlRowFadeInAnimator.addListener(listener); 43261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mControlRowFadeInAnimator.setInterpolator(mLogDecelerateInterpolator); 43361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 43461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mControlRowFadeOutAnimator = loadAnimator( 43561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu getActivity(), R.animator.lb_playback_controls_fade_out); 43661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mControlRowFadeOutAnimator.addUpdateListener(updateListener); 43761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mControlRowFadeOutAnimator.addListener(listener); 43861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mControlRowFadeOutAnimator.setInterpolator(mLogAccelerateInterpolator); 43961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 44061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 44161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private void loadOtherRowAnimator() { 44261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu final AnimatorListener listener = new AnimatorListener() { 44361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 44461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu void getViews(ArrayList<View> views) { 44561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (getVerticalGridView() == null) { 44661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return; 44761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 44861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu final int count = getVerticalGridView().getChildCount(); 44961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu for (int i = 0; i < count; i++) { 45061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu View view = getVerticalGridView().getChildAt(i); 45161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (view != null) { 45261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu views.add(view); 45361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 45461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 45561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 45661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu }; 45761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu final AnimatorUpdateListener updateListener = new AnimatorUpdateListener() { 45861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 45961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void onAnimationUpdate(ValueAnimator arg0) { 460db14dd5106afde6a39ae26448df2b81b536ebc2bCraig Stout if (getVerticalGridView() == null) { 461db14dd5106afde6a39ae26448df2b81b536ebc2bCraig Stout return; 462db14dd5106afde6a39ae26448df2b81b536ebc2bCraig Stout } 46361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu final float fraction = (Float) arg0.getAnimatedValue(); 46461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu for (View view : listener.mViews) { 46561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (getVerticalGridView().getChildPosition(view) > 0) { 46661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu view.setAlpha(fraction); 46761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu view.setTranslationY((float) mAnimationTranslateY * (1f - fraction)); 46861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 46961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 47061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 47161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu }; 47261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 47361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mOtherRowFadeInAnimator = loadAnimator( 47461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu getActivity(), R.animator.lb_playback_controls_fade_in); 47561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mOtherRowFadeInAnimator.addListener(listener); 47661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mOtherRowFadeInAnimator.addUpdateListener(updateListener); 47761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mOtherRowFadeInAnimator.setInterpolator(mLogDecelerateInterpolator); 47861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 47961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mOtherRowFadeOutAnimator = loadAnimator( 48061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu getActivity(), R.animator.lb_playback_controls_fade_out); 48161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mOtherRowFadeOutAnimator.addListener(listener); 48261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mOtherRowFadeOutAnimator.addUpdateListener(updateListener); 48361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mOtherRowFadeOutAnimator.setInterpolator(new AccelerateInterpolator()); 48461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 48561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 48661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private void loadDescriptionAnimator() { 48761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu AnimatorUpdateListener listener = new AnimatorUpdateListener() { 48861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 48961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void onAnimationUpdate(ValueAnimator arg0) { 49061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (getVerticalGridView() == null) { 49161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return; 49261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 49361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu ItemBridgeAdapter.ViewHolder adapterVh = (ItemBridgeAdapter.ViewHolder) 49461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu getVerticalGridView().findViewHolderForPosition(0); 49561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (adapterVh != null && adapterVh.getViewHolder() 49661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu instanceof PlaybackControlsRowPresenter.ViewHolder) { 49761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu final Presenter.ViewHolder vh = ((PlaybackControlsRowPresenter.ViewHolder) 49861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu adapterVh.getViewHolder()).mDescriptionViewHolder; 49961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (vh != null) { 50061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu vh.view.setAlpha((Float) arg0.getAnimatedValue()); 50161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 50261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 50361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 50461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu }; 50561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 50661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mDescriptionFadeInAnimator = loadAnimator( 50761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu getActivity(), R.animator.lb_playback_description_fade_in); 50861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mDescriptionFadeInAnimator.addUpdateListener(listener); 50961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mDescriptionFadeInAnimator.setInterpolator(mLogDecelerateInterpolator); 51061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 51161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mDescriptionFadeOutAnimator = loadAnimator( 51261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu getActivity(), R.animator.lb_playback_description_fade_out); 51361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mDescriptionFadeOutAnimator.addUpdateListener(listener); 51461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 51561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 51661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private void fade(boolean fadeIn) { 51761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (DEBUG) Log.v(TAG, "fade " + fadeIn); 51861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (getView() == null) { 51961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return; 52061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 52161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if ((fadeIn && mFadingStatus == IN) || (!fadeIn && mFadingStatus == OUT)) { 52261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (DEBUG) Log.v(TAG, "requested fade in progress"); 52361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return; 52461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 52561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if ((fadeIn && mBgAlpha == 255) || (!fadeIn && mBgAlpha == 0)) { 52661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (DEBUG) Log.v(TAG, "fade is no-op"); 52761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return; 52861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 52961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 53061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mAnimationTranslateY = getVerticalGridView().getSelectedPosition() == 0 ? 53161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mMajorFadeTranslateY : mMinorFadeTranslateY; 53261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 53361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mFadingStatus == IDLE) { 53461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (fadeIn) { 53561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mBgFadeInAnimator.start(); 53661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mControlRowFadeInAnimator.start(); 53761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mOtherRowFadeInAnimator.start(); 53861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mDescriptionFadeInAnimator.start(); 53961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } else { 54061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mBgFadeOutAnimator.start(); 54161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mControlRowFadeOutAnimator.start(); 54261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mOtherRowFadeOutAnimator.start(); 54361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mDescriptionFadeOutAnimator.start(); 54461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 54561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } else { 54661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (fadeIn) { 54761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mBgFadeOutAnimator.reverse(); 54861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mControlRowFadeOutAnimator.reverse(); 54961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mOtherRowFadeOutAnimator.reverse(); 55061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mDescriptionFadeOutAnimator.reverse(); 55161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } else { 55261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mBgFadeInAnimator.reverse(); 55361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mControlRowFadeInAnimator.reverse(); 55461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mOtherRowFadeInAnimator.reverse(); 55561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mDescriptionFadeInAnimator.reverse(); 55661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 55761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 55861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 55961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu // If fading in while control row is focused, set initial translationY so 56061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu // views slide in from below. 56161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (fadeIn && mFadingStatus == IDLE) { 56261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu final int count = getVerticalGridView().getChildCount(); 56361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu for (int i = 0; i < count; i++) { 56461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu getVerticalGridView().getChildAt(i).setTranslationY(mAnimationTranslateY); 56561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 56661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 56761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 56861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mFadingStatus = fadeIn ? IN : OUT; 56961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 57061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 57161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 57261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Sets the list of rows for the fragment. 57361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 57461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 57561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void setAdapter(ObjectAdapter adapter) { 57661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (getAdapter() != null) { 57761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu getAdapter().unregisterObserver(mObserver); 57861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 57961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu super.setAdapter(adapter); 58061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (adapter != null) { 58161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu adapter.registerObserver(mObserver); 58261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 58361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 58461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 58561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 58661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu void setVerticalGridViewLayout(VerticalGridView listview) { 58761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (listview == null) { 58861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return; 58961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 59061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu // Padding affects alignment when last row is focused 59161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu // (last is first when there's only one row). 59261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu setBottomPadding(listview, mPaddingBottom); 59361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 59461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu // Item alignment affects focused row that isn't the last. 59561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu listview.setItemAlignmentOffset(mAlignPosition); 59661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu listview.setItemAlignmentOffsetPercent(100); 59761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 59861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu // Push rows to the bottom. 59961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu listview.setWindowAlignmentOffset(0); 60061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu listview.setWindowAlignmentOffsetPercent(100); 60161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu listview.setWindowAlignment(VerticalGridView.WINDOW_ALIGN_HIGH_EDGE); 60261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 60361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 60461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private static void setBottomPadding(View view, int padding) { 60561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu view.setPadding(view.getPaddingLeft(), view.getPaddingTop(), 60661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu view.getPaddingRight(), padding); 60761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 60861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 60961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 61061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void onCreate(Bundle savedInstanceState) { 61161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu super.onCreate(savedInstanceState); 61261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 61361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mAlignPosition = 61461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu getResources().getDimensionPixelSize(R.dimen.lb_playback_controls_align_bottom); 61561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mPaddingBottom = 61661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu getResources().getDimensionPixelSize(R.dimen.lb_playback_controls_padding_bottom); 61761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mBgDarkColor = 61861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu getResources().getColor(R.color.lb_playback_controls_background_dark); 61961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mBgLightColor = 62061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu getResources().getColor(R.color.lb_playback_controls_background_light); 62161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mShowTimeMs = 62261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu getResources().getInteger(R.integer.lb_playback_controls_show_time_ms); 62361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mMajorFadeTranslateY = 62461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu getResources().getDimensionPixelSize(R.dimen.lb_playback_major_fade_translate_y); 62561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mMinorFadeTranslateY = 62661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu getResources().getDimensionPixelSize(R.dimen.lb_playback_minor_fade_translate_y); 62761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 62861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu loadBgAnimator(); 62961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu loadControlRowAnimator(); 63061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu loadOtherRowAnimator(); 63161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu loadDescriptionAnimator(); 63261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 63361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 63461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 63561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Sets the background type. 63661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * 63761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * @param type One of BG_LIGHT, BG_DARK, or BG_NONE. 63861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 63961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void setBackgroundType(int type) { 64061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu switch (type) { 64161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu case BG_LIGHT: 64261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu case BG_DARK: 64361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu case BG_NONE: 64461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (type != mBackgroundType) { 64561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mBackgroundType = type; 64661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu updateBackground(); 64761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 64861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu break; 64961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu default: 65061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu throw new IllegalArgumentException("Invalid background type"); 65161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 65261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 65361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 65461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu /** 65561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu * Returns the background type. 65661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu */ 65761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public int getBackgroundType() { 65861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return mBackgroundType; 65961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 66061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 66161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private void updateBackground() { 66261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (mRootView != null) { 66361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu int color = mBgDarkColor; 66461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu switch (mBackgroundType) { 66561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu case BG_DARK: break; 66661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu case BG_LIGHT: color = mBgLightColor; break; 66761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu case BG_NONE: color = Color.TRANSPARENT; break; 66861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 66961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mRootView.setBackground(new ColorDrawable(color)); 67061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 67161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 67261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 67361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private void updateControlsBottomSpace(ItemBridgeAdapter.ViewHolder vh) { 67461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu // Add extra space between rows 0 and 1 67561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (vh == null && getVerticalGridView() != null) { 67661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu vh = (ItemBridgeAdapter.ViewHolder) 67761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu getVerticalGridView().findViewHolderForPosition(0); 67861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 67961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (vh != null && vh.getPresenter() instanceof PlaybackControlsRowPresenter) { 68061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu final int adapterSize = getAdapter() == null ? 0 : getAdapter().size(); 68161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu ((PlaybackControlsRowPresenter) vh.getPresenter()).showBottomSpace( 68261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu (PlaybackControlsRowPresenter.ViewHolder) vh.getViewHolder(), 68361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu adapterSize > 1); 68461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 68561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 68661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 68761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private final ItemBridgeAdapter.AdapterListener mAdapterListener = 68861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu new ItemBridgeAdapter.AdapterListener() { 68961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 69061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void onAttachedToWindow(ItemBridgeAdapter.ViewHolder vh) { 69161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (DEBUG) Log.v(TAG, "onAttachedToWindow " + vh.getViewHolder().view); 69261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if ((mFadingStatus == IDLE && mBgAlpha == 0) || mFadingStatus == OUT) { 69361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (DEBUG) Log.v(TAG, "setting alpha to 0"); 69461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu vh.getViewHolder().view.setAlpha(0); 69561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 69661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (vh.getPosition() == 0 && mResetControlsToPrimaryActionsPending) { 69761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu resetControlsToPrimaryActions(vh); 69861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 69961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 70061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 70161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void onDetachedFromWindow(ItemBridgeAdapter.ViewHolder vh) { 70261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (DEBUG) Log.v(TAG, "onDetachedFromWindow " + vh.getViewHolder().view); 70361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu // Reset animation state 70461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu vh.getViewHolder().view.setAlpha(1f); 70561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu vh.getViewHolder().view.setTranslationY(0); 70661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (vh.getViewHolder() instanceof PlaybackControlsRowPresenter.ViewHolder) { 70761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu Presenter.ViewHolder descriptionVh = ((PlaybackControlsRowPresenter.ViewHolder) 70861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu vh.getViewHolder()).mDescriptionViewHolder; 70961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (descriptionVh != null) { 71061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu descriptionVh.view.setAlpha(1f); 71161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 71261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 71361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 71461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 71561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void onBind(ItemBridgeAdapter.ViewHolder vh) { 71661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu if (vh.getPosition() == 0) { 71761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu updateControlsBottomSpace(vh); 71861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 71961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 72061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu }; 72161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 72261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 72361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public View onCreateView(LayoutInflater inflater, ViewGroup container, 72461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu Bundle savedInstanceState) { 72561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mRootView = super.onCreateView(inflater, container, savedInstanceState); 72661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mBgAlpha = 255; 72761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu updateBackground(); 72861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu getRowsSupportFragment().setExternalAdapterListener(mAdapterListener); 72961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu return mRootView; 73061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 73161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 73261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu @Override 73361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void onDestroyView() { 73461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mRootView = null; 73561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu super.onDestroyView(); 73661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 73761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 73861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu private final DataObserver mObserver = new DataObserver() { 73961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void onChanged() { 74061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu updateControlsBottomSpace(null); 74161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 74261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu }; 74361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 74461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu static abstract class AnimatorListener implements Animator.AnimatorListener { 74561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu ArrayList<View> mViews = new ArrayList<View>(); 74661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu ArrayList<Integer> mLayerType = new ArrayList<Integer>(); 74761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu 74861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void onAnimationCancel(Animator animation) { 74961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 75061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void onAnimationRepeat(Animator animation) { 75161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 75261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void onAnimationStart(Animator animation) { 75361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu getViews(mViews); 75461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu for (View view : mViews) { 75561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mLayerType.add(view.getLayerType()); 75661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu view.setLayerType(View.LAYER_TYPE_HARDWARE, null); 75761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 75861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 75961905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu public void onAnimationEnd(Animator animation) { 76061905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu for (int i = 0; i < mViews.size(); i++) { 76161905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mViews.get(i).setLayerType(mLayerType.get(i), null); 76261905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 76361905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mLayerType.clear(); 76461905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu mViews.clear(); 76561905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu } 76661905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu abstract void getViews(ArrayList<View> views); 76761905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu }; 76861905b0b52c50018dcaebcd79699c39b8f28d622Dake Gu} 769