FileDocCategorySizeDatePackage
PlaybackOverlayFragment.javaAPI DocAndroid 5.1 API27620Thu Mar 12 22:22:56 GMT 2015android.support.v17.leanback.app

PlaybackOverlayFragment

public class PlaybackOverlayFragment extends DetailsFragment
A fragment for displaying playback controls and related content. The {@link android.support.v17.leanback.widget.PlaybackControlsRow} is expected to be at position 0 in the adapter.

Fields Summary
public static final int
BG_NONE
No background.
public static final int
BG_DARK
A dark translucent background.
public static final int
BG_LIGHT
A light translucent background.
private static final String
TAG
private static final boolean
DEBUG
private static final int
ANIMATION_MULTIPLIER
private static int
START_FADE_OUT
private static final int
IDLE
private static final int
IN
private static final int
OUT
private int
mAlignPosition
private int
mPaddingBottom
private android.view.View
mRootView
private int
mBackgroundType
private int
mBgDarkColor
private int
mBgLightColor
private int
mShowTimeMs
private int
mMajorFadeTranslateY
private int
mMinorFadeTranslateY
private int
mAnimationTranslateY
private OnFadeCompleteListener
mFadeCompleteListener
private InputEventHandler
mInputEventHandler
private boolean
mFadingEnabled
private int
mFadingStatus
private int
mBgAlpha
private android.animation.ValueAnimator
mBgFadeInAnimator
private android.animation.ValueAnimator
mBgFadeOutAnimator
private android.animation.ValueAnimator
mControlRowFadeInAnimator
private android.animation.ValueAnimator
mControlRowFadeOutAnimator
private android.animation.ValueAnimator
mDescriptionFadeInAnimator
private android.animation.ValueAnimator
mDescriptionFadeOutAnimator
private android.animation.ValueAnimator
mOtherRowFadeInAnimator
private android.animation.ValueAnimator
mOtherRowFadeOutAnimator
private boolean
mTranslateAnimationEnabled
private boolean
mResetControlsToPrimaryActionsPending
private RecyclerView.ItemAnimator
mItemAnimator
private final Animator.AnimatorListener
mFadeListener
private final android.os.Handler
mHandler
private final VerticalGridView.OnTouchInterceptListener
mOnTouchInterceptListener
private final VerticalGridView.OnKeyInterceptListener
mOnKeyInterceptListener
private android.animation.TimeInterpolator
mLogDecelerateInterpolator
private android.animation.TimeInterpolator
mLogAccelerateInterpolator
private final ItemBridgeAdapter.AdapterListener
mAdapterListener
private final android.support.v17.leanback.widget.ObjectAdapter.DataObserver
mObserver
Constructors Summary
Methods Summary
private voidenableVerticalGridAnimations(boolean enable)

        if (getVerticalGridView() != null) {
            getVerticalGridView().setAnimateChildLayout(enable);
        }
    
private voidfade(boolean fadeIn)

        if (DEBUG) Log.v(TAG, "fade " + fadeIn);
        if (getView() == null) {
            return;
        }
        if ((fadeIn && mFadingStatus == IN) || (!fadeIn && mFadingStatus == OUT)) {
            if (DEBUG) Log.v(TAG, "requested fade in progress");
            return;
        }
        if ((fadeIn && mBgAlpha == 255) || (!fadeIn && mBgAlpha == 0)) {
            if (DEBUG) Log.v(TAG, "fade is no-op");
            return;
        }

        mAnimationTranslateY = getVerticalGridView().getSelectedPosition() == 0 ?
                mMajorFadeTranslateY : mMinorFadeTranslateY;

        if (mFadingStatus == IDLE) {
            if (fadeIn) {
                mBgFadeInAnimator.start();
                mControlRowFadeInAnimator.start();
                mOtherRowFadeInAnimator.start();
                mDescriptionFadeInAnimator.start();
            } else {
                mBgFadeOutAnimator.start();
                mControlRowFadeOutAnimator.start();
                mOtherRowFadeOutAnimator.start();
                mDescriptionFadeOutAnimator.start();
            }
        } else {
            if (fadeIn) {
                mBgFadeOutAnimator.reverse();
                mControlRowFadeOutAnimator.reverse();
                mOtherRowFadeOutAnimator.reverse();
                mDescriptionFadeOutAnimator.reverse();
            } else {
                mBgFadeInAnimator.reverse();
                mControlRowFadeInAnimator.reverse();
                mOtherRowFadeInAnimator.reverse();
                mDescriptionFadeInAnimator.reverse();
            }
        }

        // If fading in while control row is focused, set initial translationY so
        // views slide in from below.
        if (fadeIn && mFadingStatus == IDLE) {
            final int count = getVerticalGridView().getChildCount();
            for (int i = 0; i < count; i++) {
                getVerticalGridView().getChildAt(i).setTranslationY(mAnimationTranslateY);
            }
        }

        mFadingStatus = fadeIn ? IN : OUT;
    
public intgetBackgroundType()
Returns the background type.

        return mBackgroundType;
    
private android.view.ViewgetControlRowView()


       
        if (getVerticalGridView() == null) {
            return null;
        }
        RecyclerView.ViewHolder vh = getVerticalGridView().findViewHolderForPosition(0);
        if (vh == null) {
            return null;
        }
        return vh.itemView;
    
public android.support.v17.leanback.app.PlaybackOverlayFragment$OnFadeCompleteListenergetFadeCompleteListener()
Returns the listener to be called when fade in or out has completed.

        return mFadeCompleteListener;
    
public final android.support.v17.leanback.app.PlaybackOverlayFragment$InputEventHandlergetInputEventHandler()
Returns the input event handler.

        return mInputEventHandler;
    
private static booleanisConsumableKey(android.view.KeyEvent keyEvent)

        if (keyEvent.isSystem()) {
            return false;
        }
        return true;
    
public booleanisFadingEnabled()
Returns true if view fading is enabled.

        return mFadingEnabled;
    
private static android.animation.ValueAnimatorloadAnimator(android.content.Context context, int resId)

        ValueAnimator animator = (ValueAnimator) AnimatorInflater.loadAnimator(context, resId);
        animator.setDuration(animator.getDuration() * ANIMATION_MULTIPLIER);
        return animator;
    
private voidloadBgAnimator()

        AnimatorUpdateListener listener = new AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator arg0) {
                setBgAlpha((Integer) arg0.getAnimatedValue());
            }
        };

        mBgFadeInAnimator = loadAnimator(getActivity(), R.animator.lb_playback_bg_fade_in);
        mBgFadeInAnimator.addUpdateListener(listener);
        mBgFadeInAnimator.addListener(mFadeListener);

        mBgFadeOutAnimator = loadAnimator(getActivity(), R.animator.lb_playback_bg_fade_out);
        mBgFadeOutAnimator.addUpdateListener(listener);
        mBgFadeOutAnimator.addListener(mFadeListener);
    
private voidloadControlRowAnimator()

        final AnimatorListener listener = new AnimatorListener() {
            @Override
            void getViews(ArrayList<View> views) {
                View view = getControlRowView();
                if (view != null) {
                    views.add(view);
                }
            }
        };
        final AnimatorUpdateListener updateListener = new AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator arg0) {
                View view = getControlRowView();
                if (view != null) {
                    final float fraction = (Float) arg0.getAnimatedValue();
                    if (DEBUG) Log.v(TAG, "fraction " + fraction);
                    view.setAlpha(fraction);
                    view.setTranslationY((float) mAnimationTranslateY * (1f - fraction));
                }
            }
        };

        mControlRowFadeInAnimator = loadAnimator(
                getActivity(), R.animator.lb_playback_controls_fade_in);
        mControlRowFadeInAnimator.addUpdateListener(updateListener);
        mControlRowFadeInAnimator.addListener(listener);
        mControlRowFadeInAnimator.setInterpolator(mLogDecelerateInterpolator);

        mControlRowFadeOutAnimator = loadAnimator(
                getActivity(), R.animator.lb_playback_controls_fade_out);
        mControlRowFadeOutAnimator.addUpdateListener(updateListener);
        mControlRowFadeOutAnimator.addListener(listener);
        mControlRowFadeOutAnimator.setInterpolator(mLogAccelerateInterpolator);
    
private voidloadDescriptionAnimator()

        AnimatorUpdateListener listener = new AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator arg0) {
                if (getVerticalGridView() == null) {
                    return;
                }
                ItemBridgeAdapter.ViewHolder adapterVh = (ItemBridgeAdapter.ViewHolder)
                        getVerticalGridView().findViewHolderForPosition(0);
                if (adapterVh != null && adapterVh.getViewHolder()
                        instanceof PlaybackControlsRowPresenter.ViewHolder) {
                    final Presenter.ViewHolder vh = ((PlaybackControlsRowPresenter.ViewHolder)
                            adapterVh.getViewHolder()).mDescriptionViewHolder;
                    if (vh != null) {
                        vh.view.setAlpha((Float) arg0.getAnimatedValue());
                    }
                }
            }
        };

        mDescriptionFadeInAnimator = loadAnimator(
                getActivity(), R.animator.lb_playback_description_fade_in);
        mDescriptionFadeInAnimator.addUpdateListener(listener);
        mDescriptionFadeInAnimator.setInterpolator(mLogDecelerateInterpolator);

        mDescriptionFadeOutAnimator = loadAnimator(
                getActivity(), R.animator.lb_playback_description_fade_out);
        mDescriptionFadeOutAnimator.addUpdateListener(listener);
    
private voidloadOtherRowAnimator()

        final AnimatorListener listener = new AnimatorListener() {
            @Override
            void getViews(ArrayList<View> views) {
                if (getVerticalGridView() == null) {
                    return;
                }
                final int count = getVerticalGridView().getChildCount();
                for (int i = 0; i < count; i++) {
                    View view = getVerticalGridView().getChildAt(i);
                    if (view != null) {
                        views.add(view);
                    }
                }
            }
        };
        final AnimatorUpdateListener updateListener = new AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator arg0) {
                if (getVerticalGridView() == null) {
                    return;
                }
                final float fraction = (Float) arg0.getAnimatedValue();
                for (View view : listener.mViews) {
                    if (getVerticalGridView().getChildPosition(view) > 0) {
                        view.setAlpha(fraction);
                        view.setTranslationY((float) mAnimationTranslateY * (1f - fraction));
                    }
                }
            }
        };

        mOtherRowFadeInAnimator = loadAnimator(
                getActivity(), R.animator.lb_playback_controls_fade_in);
        mOtherRowFadeInAnimator.addListener(listener);
        mOtherRowFadeInAnimator.addUpdateListener(updateListener);
        mOtherRowFadeInAnimator.setInterpolator(mLogDecelerateInterpolator);

        mOtherRowFadeOutAnimator = loadAnimator(
                getActivity(), R.animator.lb_playback_controls_fade_out);
        mOtherRowFadeOutAnimator.addListener(listener);
        mOtherRowFadeOutAnimator.addUpdateListener(updateListener);
        mOtherRowFadeOutAnimator.setInterpolator(new AccelerateInterpolator());
    
public voidonCreate(android.os.Bundle savedInstanceState)

        super.onCreate(savedInstanceState);

        mAlignPosition =
                getResources().getDimensionPixelSize(R.dimen.lb_playback_controls_align_bottom);
        mPaddingBottom =
                getResources().getDimensionPixelSize(R.dimen.lb_playback_controls_padding_bottom);
        mBgDarkColor =
                getResources().getColor(R.color.lb_playback_controls_background_dark);
        mBgLightColor =
                getResources().getColor(R.color.lb_playback_controls_background_light);
        mShowTimeMs =
                getResources().getInteger(R.integer.lb_playback_controls_show_time_ms);
        mMajorFadeTranslateY =
                getResources().getDimensionPixelSize(R.dimen.lb_playback_major_fade_translate_y);
        mMinorFadeTranslateY =
                getResources().getDimensionPixelSize(R.dimen.lb_playback_minor_fade_translate_y);

        loadBgAnimator();
        loadControlRowAnimator();
        loadOtherRowAnimator();
        loadDescriptionAnimator();
    
public android.view.ViewonCreateView(android.view.LayoutInflater inflater, android.view.ViewGroup container, android.os.Bundle savedInstanceState)


    
         
              
        mRootView = super.onCreateView(inflater, container, savedInstanceState);
        mBgAlpha = 255;
        updateBackground();
        getRowsFragment().setExternalAdapterListener(mAdapterListener);
        return mRootView;
    
public voidonDestroyView()

        mRootView = null;
        super.onDestroyView();
    
private booleanonInterceptInputEvent(android.view.InputEvent event)

        if (DEBUG) Log.v(TAG, "onInterceptInputEvent status " + mFadingStatus +
                " mBgAlpha " + mBgAlpha + " event " + event);
        final boolean controlsHidden = (mFadingStatus == IDLE && mBgAlpha == 0);
        boolean consumeEvent = controlsHidden;
        int keyCode = KeyEvent.KEYCODE_UNKNOWN;

        if (event instanceof KeyEvent) {
            if (consumeEvent) {
                consumeEvent = isConsumableKey((KeyEvent) event);
            }
            keyCode = ((KeyEvent) event).getKeyCode();
        }
        if (!consumeEvent && mInputEventHandler != null) {
            consumeEvent = mInputEventHandler.handleInputEvent(event);
        }
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            // If fading enabled and controls are not hidden, back will be consumed to fade
            // them out (even if the key was consumed by the handler).
            if (mFadingEnabled && !controlsHidden) {
                consumeEvent = true;
                mHandler.removeMessages(START_FADE_OUT);
                fade(false);
            } else if (consumeEvent) {
                tickle();
            }
        } else {
            // Any other key will show the controls
            tickle();
        }
        return consumeEvent;
    
public voidonResume()

        super.onResume();
        if (mFadingEnabled) {
            setBgAlpha(0);
            fade(true);
        }
        getVerticalGridView().setOnTouchInterceptListener(mOnTouchInterceptListener);
        getVerticalGridView().setOnKeyInterceptListener(mOnKeyInterceptListener);
    
private voidresetControlsToPrimaryActions(ItemBridgeAdapter.ViewHolder vh)

        if (vh == null && getVerticalGridView() != null) {
            vh = (ItemBridgeAdapter.ViewHolder) getVerticalGridView().findViewHolderForPosition(0);
        }
        if (vh == null) {
            mResetControlsToPrimaryActionsPending = true;
        } else if (vh.getPresenter() instanceof PlaybackControlsRowPresenter) {
            mResetControlsToPrimaryActionsPending = false;
            ((PlaybackControlsRowPresenter) vh.getPresenter()).showPrimaryActions(
                    (PlaybackControlsRowPresenter.ViewHolder) vh.getViewHolder());
        }
    
public voidsetAdapter(android.support.v17.leanback.widget.ObjectAdapter adapter)
Sets the list of rows for the fragment.

        if (getAdapter() != null) {
            getAdapter().unregisterObserver(mObserver);
        }
        super.setAdapter(adapter);
        if (adapter != null) {
            adapter.registerObserver(mObserver);
        }
    
public voidsetBackgroundType(int type)
Sets the background type.

param
type One of BG_LIGHT, BG_DARK, or BG_NONE.

        switch (type) {
        case BG_LIGHT:
        case BG_DARK:
        case BG_NONE:
            if (type != mBackgroundType) {
                mBackgroundType = type;
                updateBackground();
            }
            break;
        default:
            throw new IllegalArgumentException("Invalid background type");
        }
    
private voidsetBgAlpha(int alpha)


        
        mBgAlpha = alpha;
        if (mRootView != null) {
            mRootView.getBackground().setAlpha(alpha);
        }
    
private static voidsetBottomPadding(android.view.View view, int padding)

        view.setPadding(view.getPaddingLeft(), view.getPaddingTop(),
                view.getPaddingRight(), padding);
    
public voidsetFadeCompleteListener(android.support.v17.leanback.app.PlaybackOverlayFragment$OnFadeCompleteListener listener)
Sets the listener to be called when fade in or out has completed.

        mFadeCompleteListener = listener;
    
public voidsetFadingEnabled(boolean enabled)
Enables or disables view fading. If enabled, the view will be faded in when the fragment starts, and will fade out after a time period. The timeout period is reset each time {@link #tickle} is called.

        if (DEBUG) Log.v(TAG, "setFadingEnabled " + enabled);
        if (enabled != mFadingEnabled) {
            mFadingEnabled = enabled;
            if (mFadingEnabled) {
                if (isResumed() && mFadingStatus == IDLE
                        && !mHandler.hasMessages(START_FADE_OUT)) {
                    startFadeTimer();
                }
            } else {
                // Ensure fully opaque
                mHandler.removeMessages(START_FADE_OUT);
                fade(true);
            }
        }
    
public final voidsetInputEventHandler(android.support.v17.leanback.app.PlaybackOverlayFragment$InputEventHandler handler)
Sets the input event handler.

        mInputEventHandler = handler;
    
voidsetVerticalGridViewLayout(android.support.v17.leanback.widget.VerticalGridView listview)

        if (listview == null) {
            return;
        }
        // Padding affects alignment when last row is focused
        // (last is first when there's only one row).
        setBottomPadding(listview, mPaddingBottom);

        // Item alignment affects focused row that isn't the last.
        listview.setItemAlignmentOffset(mAlignPosition);
        listview.setItemAlignmentOffsetPercent(100);

        // Push rows to the bottom.
        listview.setWindowAlignmentOffset(0);
        listview.setWindowAlignmentOffsetPercent(100);
        listview.setWindowAlignment(VerticalGridView.WINDOW_ALIGN_HIGH_EDGE);
    
private voidstartFadeTimer()

        if (mHandler != null) {
            mHandler.removeMessages(START_FADE_OUT);
            mHandler.sendEmptyMessageDelayed(START_FADE_OUT, mShowTimeMs);
        }
    
public voidtickle()
Tickles the playback controls. Fades in the view if it was faded out, otherwise resets the fade out timer. Tickling on input events is handled by the fragment.

        if (DEBUG) Log.v(TAG, "tickle enabled " + mFadingEnabled + " isResumed " + isResumed());
        if (!mFadingEnabled || !isResumed()) {
            return;
        }
        if (mHandler.hasMessages(START_FADE_OUT)) {
            // Restart the timer
            startFadeTimer();
        } else {
            fade(true);
        }
    
private voidupdateBackground()

        if (mRootView != null) {
            int color = mBgDarkColor;
            switch (mBackgroundType) {
                case BG_DARK: break;
                case BG_LIGHT: color = mBgLightColor; break;
                case BG_NONE: color = Color.TRANSPARENT; break;
            }
            mRootView.setBackground(new ColorDrawable(color));
        }
    
private voidupdateControlsBottomSpace(ItemBridgeAdapter.ViewHolder vh)

        // Add extra space between rows 0 and 1
        if (vh == null && getVerticalGridView() != null) {
            vh = (ItemBridgeAdapter.ViewHolder)
                    getVerticalGridView().findViewHolderForPosition(0);
        }
        if (vh != null && vh.getPresenter() instanceof PlaybackControlsRowPresenter) {
            final int adapterSize = getAdapter() == null ? 0 : getAdapter().size();
            ((PlaybackControlsRowPresenter) vh.getPresenter()).showBottomSpace(
                    (PlaybackControlsRowPresenter.ViewHolder) vh.getViewHolder(),
                    adapterSize > 1);
        }