PlaybackOverlaySupportFragment.java revision eb66dab544c4c1eabe4d469b7cea348d4b01e664
1/* This file is auto-generated from PlaybackOverlayFragment.java. DO NOT MODIFY. */ 2 3/* 4 * Copyright (C) 2014 The Android Open Source Project 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 7 * in compliance with the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software distributed under the License 12 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 13 * or implied. See the License for the specific language governing permissions and limitations under 14 * the License. 15 */ 16package android.support.v17.leanback.app; 17 18import android.graphics.Color; 19import android.graphics.drawable.ColorDrawable; 20import android.animation.Animator; 21import android.animation.AnimatorInflater; 22import android.animation.TimeInterpolator; 23import android.animation.ValueAnimator; 24import android.view.InputEvent; 25import android.view.animation.AccelerateInterpolator; 26import android.animation.ValueAnimator.AnimatorUpdateListener; 27import android.content.Context; 28import android.os.Bundle; 29import android.os.Handler; 30import android.os.Message; 31import android.support.v7.widget.RecyclerView; 32import android.support.v17.leanback.R; 33import android.support.v17.leanback.animation.LogAccelerateInterpolator; 34import android.support.v17.leanback.animation.LogDecelerateInterpolator; 35import android.support.v17.leanback.widget.Presenter; 36import android.support.v17.leanback.widget.ItemBridgeAdapter; 37import android.support.v17.leanback.widget.ObjectAdapter; 38import android.support.v17.leanback.widget.ObjectAdapter.DataObserver; 39import android.support.v17.leanback.widget.VerticalGridView; 40import android.support.v17.leanback.widget.PlaybackControlsRowPresenter; 41import android.util.Log; 42import android.view.KeyEvent; 43import android.view.LayoutInflater; 44import android.view.MotionEvent; 45import android.view.View; 46import android.view.ViewGroup; 47 48import java.util.ArrayList; 49 50/** 51 * A fragment for displaying playback controls and related content. 52 * The {@link android.support.v17.leanback.widget.PlaybackControlsRow} is expected to be 53 * at position 0 in the adapter. 54 */ 55public class PlaybackOverlaySupportFragment extends DetailsSupportFragment { 56 57 /** 58 * No background. 59 */ 60 public static final int BG_NONE = 0; 61 62 /** 63 * A dark translucent background. 64 */ 65 public static final int BG_DARK = 1; 66 67 /** 68 * A light translucent background. 69 */ 70 public static final int BG_LIGHT = 2; 71 72 public static class OnFadeCompleteListener { 73 public void onFadeInComplete() { 74 } 75 public void onFadeOutComplete() { 76 } 77 } 78 79 public interface InputEventHandler { 80 /** 81 * Called when an {@link InputEvent} is received. 82 * 83 * @return If the event should be consumed, return true. To allow the event to 84 * continue on to the next handler, return false. 85 */ 86 public boolean handleInputEvent(InputEvent event); 87 } 88 89 private static final String TAG = "PlaybackOverlaySupportFragment"; 90 private static final boolean DEBUG = false; 91 private static final int ANIMATION_MULTIPLIER = 1; 92 93 private static int START_FADE_OUT = 1; 94 95 // Fading status 96 private static final int IDLE = 0; 97 private static final int IN = 1; 98 private static final int OUT = 2; 99 100 private int mAlignPosition; 101 private int mPaddingBottom; 102 private View mRootView; 103 private int mBackgroundType = BG_DARK; 104 private int mBgDarkColor; 105 private int mBgLightColor; 106 private int mShowTimeMs; 107 private int mMajorFadeTranslateY, mMinorFadeTranslateY; 108 private int mAnimationTranslateY; 109 private OnFadeCompleteListener mFadeCompleteListener; 110 private InputEventHandler mInputEventHandler; 111 private boolean mFadingEnabled = true; 112 private int mFadingStatus = IDLE; 113 private int mBgAlpha; 114 private ValueAnimator mBgFadeInAnimator, mBgFadeOutAnimator; 115 private ValueAnimator mControlRowFadeInAnimator, mControlRowFadeOutAnimator; 116 private ValueAnimator mDescriptionFadeInAnimator, mDescriptionFadeOutAnimator; 117 private ValueAnimator mOtherRowFadeInAnimator, mOtherRowFadeOutAnimator; 118 private boolean mTranslateAnimationEnabled; 119 private boolean mResetControlsToPrimaryActionsPending; 120 private RecyclerView.ItemAnimator mItemAnimator; 121 122 private final Animator.AnimatorListener mFadeListener = 123 new Animator.AnimatorListener() { 124 @Override 125 public void onAnimationStart(Animator animation) { 126 enableVerticalGridAnimations(false); 127 } 128 @Override 129 public void onAnimationRepeat(Animator animation) { 130 } 131 @Override 132 public void onAnimationCancel(Animator animation) { 133 } 134 @Override 135 public void onAnimationEnd(Animator animation) { 136 if (DEBUG) Log.v(TAG, "onAnimationEnd " + mBgAlpha); 137 if (mBgAlpha > 0) { 138 enableVerticalGridAnimations(true); 139 startFadeTimer(); 140 if (mFadeCompleteListener != null) { 141 mFadeCompleteListener.onFadeInComplete(); 142 } 143 } else { 144 if (getVerticalGridView() != null) { 145 // Reset focus to the controls row 146 getVerticalGridView().setSelectedPosition(0); 147 resetControlsToPrimaryActions(null); 148 } 149 if (mFadeCompleteListener != null) { 150 mFadeCompleteListener.onFadeOutComplete(); 151 } 152 } 153 mFadingStatus = IDLE; 154 } 155 }; 156 157 private final Handler mHandler = new Handler() { 158 @Override 159 public void handleMessage(Message message) { 160 if (message.what == START_FADE_OUT && mFadingEnabled) { 161 fade(false); 162 } 163 } 164 }; 165 166 private final VerticalGridView.OnTouchInterceptListener mOnTouchInterceptListener = 167 new VerticalGridView.OnTouchInterceptListener() { 168 public boolean onInterceptTouchEvent(MotionEvent event) { 169 return onInterceptInputEvent(event); 170 } 171 }; 172 173 private final VerticalGridView.OnMotionInterceptListener mOnMotionInterceptListener = 174 new VerticalGridView.OnMotionInterceptListener() { 175 public boolean onInterceptMotionEvent(MotionEvent event) { 176 return onInterceptInputEvent(event); 177 } 178 }; 179 180 private final VerticalGridView.OnKeyInterceptListener mOnKeyInterceptListener = 181 new VerticalGridView.OnKeyInterceptListener() { 182 public boolean onInterceptKeyEvent(KeyEvent event) { 183 return onInterceptInputEvent(event); 184 } 185 }; 186 187 private void setBgAlpha(int alpha) { 188 mBgAlpha = alpha; 189 if (mRootView != null) { 190 mRootView.getBackground().setAlpha(alpha); 191 } 192 } 193 194 private void enableVerticalGridAnimations(boolean enable) { 195 if (getVerticalGridView() != null) { 196 getVerticalGridView().setAnimateChildLayout(enable); 197 } 198 } 199 200 private void resetControlsToPrimaryActions(ItemBridgeAdapter.ViewHolder vh) { 201 if (vh == null && getVerticalGridView() != null) { 202 vh = (ItemBridgeAdapter.ViewHolder) getVerticalGridView().findViewHolderForPosition(0); 203 } 204 if (vh == null) { 205 mResetControlsToPrimaryActionsPending = true; 206 } else if (vh.getPresenter() instanceof PlaybackControlsRowPresenter) { 207 mResetControlsToPrimaryActionsPending = false; 208 ((PlaybackControlsRowPresenter) vh.getPresenter()).showPrimaryActions( 209 (PlaybackControlsRowPresenter.ViewHolder) vh.getViewHolder()); 210 } 211 } 212 213 /** 214 * Enables or disables view fading. If enabled, 215 * the view will be faded in when the fragment starts, 216 * and will fade out after a time period. The timeout 217 * period is reset each time {@link #tickle} is called. 218 * 219 */ 220 public void setFadingEnabled(boolean enabled) { 221 if (DEBUG) Log.v(TAG, "setFadingEnabled " + enabled); 222 if (enabled != mFadingEnabled) { 223 mFadingEnabled = enabled; 224 if (isResumed()) { 225 if (mFadingEnabled) { 226 if (mFadingStatus == IDLE && !mHandler.hasMessages(START_FADE_OUT)) { 227 startFadeTimer(); 228 } 229 } else { 230 // Ensure fully opaque 231 mHandler.removeMessages(START_FADE_OUT); 232 fade(true); 233 } 234 } 235 } 236 } 237 238 /** 239 * Returns true if view fading is enabled. 240 */ 241 public boolean isFadingEnabled() { 242 return mFadingEnabled; 243 } 244 245 /** 246 * Sets the listener to be called when fade in or out has completed. 247 */ 248 public void setFadeCompleteListener(OnFadeCompleteListener listener) { 249 mFadeCompleteListener = listener; 250 } 251 252 /** 253 * Returns the listener to be called when fade in or out has completed. 254 */ 255 public OnFadeCompleteListener getFadeCompleteListener() { 256 return mFadeCompleteListener; 257 } 258 259 /** 260 * Sets the input event handler. 261 */ 262 public final void setInputEventHandler(InputEventHandler handler) { 263 mInputEventHandler = handler; 264 } 265 266 /** 267 * Returns the input event handler. 268 */ 269 public final InputEventHandler getInputEventListener() { 270 return mInputEventHandler; 271 } 272 273 /** 274 * Tickles the playback controls. Fades in the view if it was faded out, 275 * otherwise resets the fade out timer. Tickling on input events is handled 276 * by the fragment. 277 */ 278 public void tickle() { 279 if (DEBUG) Log.v(TAG, "tickle enabled " + mFadingEnabled + " isResumed " + isResumed()); 280 if (!mFadingEnabled || !isResumed()) { 281 return; 282 } 283 if (mHandler.hasMessages(START_FADE_OUT)) { 284 // Restart the timer 285 startFadeTimer(); 286 } else { 287 fade(true); 288 } 289 } 290 291 private static boolean isConsumableKey(KeyEvent keyEvent) { 292 if (keyEvent.isSystem()) { 293 return false; 294 } 295 return true; 296 } 297 298 private boolean onInterceptInputEvent(InputEvent event) { 299 if (DEBUG) Log.v(TAG, "onInterceptInputEvent status " + mFadingStatus + " event " + event); 300 boolean consumeEvent = (mFadingStatus == IDLE && mBgAlpha == 0); 301 if (event instanceof KeyEvent) { 302 if (consumeEvent) { 303 consumeEvent = isConsumableKey((KeyEvent) event); 304 } 305 int keyCode = ((KeyEvent) event).getKeyCode(); 306 // Back key typically means we're leaving the fragment 307 if (keyCode != KeyEvent.KEYCODE_BACK) { 308 tickle(); 309 } 310 } else { 311 tickle(); 312 } 313 if (!consumeEvent && mInputEventHandler != null) { 314 consumeEvent = mInputEventHandler.handleInputEvent(event); 315 } 316 tickle(); 317 return consumeEvent; 318 } 319 320 @Override 321 public void onResume() { 322 super.onResume(); 323 if (mFadingEnabled) { 324 setBgAlpha(0); 325 fade(true); 326 } 327 getVerticalGridView().setOnTouchInterceptListener(mOnTouchInterceptListener); 328 getVerticalGridView().setOnMotionInterceptListener(mOnMotionInterceptListener); 329 getVerticalGridView().setOnKeyInterceptListener(mOnKeyInterceptListener); 330 } 331 332 private void startFadeTimer() { 333 if (mHandler != null) { 334 mHandler.removeMessages(START_FADE_OUT); 335 mHandler.sendEmptyMessageDelayed(START_FADE_OUT, mShowTimeMs); 336 } 337 } 338 339 private static ValueAnimator loadAnimator(Context context, int resId) { 340 ValueAnimator animator = (ValueAnimator) AnimatorInflater.loadAnimator(context, resId); 341 animator.setDuration(animator.getDuration() * ANIMATION_MULTIPLIER); 342 return animator; 343 } 344 345 private void loadBgAnimator() { 346 AnimatorUpdateListener listener = new AnimatorUpdateListener() { 347 @Override 348 public void onAnimationUpdate(ValueAnimator arg0) { 349 setBgAlpha((Integer) arg0.getAnimatedValue()); 350 } 351 }; 352 353 mBgFadeInAnimator = loadAnimator(getActivity(), R.animator.lb_playback_bg_fade_in); 354 mBgFadeInAnimator.addUpdateListener(listener); 355 mBgFadeInAnimator.addListener(mFadeListener); 356 357 mBgFadeOutAnimator = loadAnimator(getActivity(), R.animator.lb_playback_bg_fade_out); 358 mBgFadeOutAnimator.addUpdateListener(listener); 359 mBgFadeOutAnimator.addListener(mFadeListener); 360 } 361 362 private TimeInterpolator mLogDecelerateInterpolator = new LogDecelerateInterpolator(100,0); 363 private TimeInterpolator mLogAccelerateInterpolator = new LogAccelerateInterpolator(100,0); 364 365 private View getControlRowView() { 366 if (getVerticalGridView() == null) { 367 return null; 368 } 369 RecyclerView.ViewHolder vh = getVerticalGridView().findViewHolderForPosition(0); 370 if (vh == null) { 371 return null; 372 } 373 return vh.itemView; 374 } 375 376 private void loadControlRowAnimator() { 377 final AnimatorListener listener = new AnimatorListener() { 378 @Override 379 void getViews(ArrayList<View> views) { 380 View view = getControlRowView(); 381 if (view != null) { 382 views.add(view); 383 } 384 } 385 }; 386 final AnimatorUpdateListener updateListener = new AnimatorUpdateListener() { 387 @Override 388 public void onAnimationUpdate(ValueAnimator arg0) { 389 View view = getControlRowView(); 390 if (view != null) { 391 final float fraction = (Float) arg0.getAnimatedValue(); 392 if (DEBUG) Log.v(TAG, "fraction " + fraction); 393 view.setAlpha(fraction); 394 view.setTranslationY((float) mAnimationTranslateY * (1f - fraction)); 395 } 396 } 397 }; 398 399 mControlRowFadeInAnimator = loadAnimator( 400 getActivity(), R.animator.lb_playback_controls_fade_in); 401 mControlRowFadeInAnimator.addUpdateListener(updateListener); 402 mControlRowFadeInAnimator.addListener(listener); 403 mControlRowFadeInAnimator.setInterpolator(mLogDecelerateInterpolator); 404 405 mControlRowFadeOutAnimator = loadAnimator( 406 getActivity(), R.animator.lb_playback_controls_fade_out); 407 mControlRowFadeOutAnimator.addUpdateListener(updateListener); 408 mControlRowFadeOutAnimator.addListener(listener); 409 mControlRowFadeOutAnimator.setInterpolator(mLogAccelerateInterpolator); 410 } 411 412 private void loadOtherRowAnimator() { 413 final AnimatorListener listener = new AnimatorListener() { 414 @Override 415 void getViews(ArrayList<View> views) { 416 if (getVerticalGridView() == null) { 417 return; 418 } 419 final int count = getVerticalGridView().getChildCount(); 420 for (int i = 0; i < count; i++) { 421 View view = getVerticalGridView().getChildAt(i); 422 if (view != null) { 423 views.add(view); 424 } 425 } 426 } 427 }; 428 final AnimatorUpdateListener updateListener = new AnimatorUpdateListener() { 429 @Override 430 public void onAnimationUpdate(ValueAnimator arg0) { 431 final float fraction = (Float) arg0.getAnimatedValue(); 432 for (View view : listener.mViews) { 433 if (getVerticalGridView().getChildPosition(view) > 0) { 434 view.setAlpha(fraction); 435 view.setTranslationY((float) mAnimationTranslateY * (1f - fraction)); 436 } 437 } 438 } 439 }; 440 441 mOtherRowFadeInAnimator = loadAnimator( 442 getActivity(), R.animator.lb_playback_controls_fade_in); 443 mOtherRowFadeInAnimator.addListener(listener); 444 mOtherRowFadeInAnimator.addUpdateListener(updateListener); 445 mOtherRowFadeInAnimator.setInterpolator(mLogDecelerateInterpolator); 446 447 mOtherRowFadeOutAnimator = loadAnimator( 448 getActivity(), R.animator.lb_playback_controls_fade_out); 449 mOtherRowFadeOutAnimator.addListener(listener); 450 mOtherRowFadeOutAnimator.addUpdateListener(updateListener); 451 mOtherRowFadeOutAnimator.setInterpolator(new AccelerateInterpolator()); 452 } 453 454 private void loadDescriptionAnimator() { 455 AnimatorUpdateListener listener = new AnimatorUpdateListener() { 456 @Override 457 public void onAnimationUpdate(ValueAnimator arg0) { 458 if (getVerticalGridView() == null) { 459 return; 460 } 461 ItemBridgeAdapter.ViewHolder adapterVh = (ItemBridgeAdapter.ViewHolder) 462 getVerticalGridView().findViewHolderForPosition(0); 463 if (adapterVh != null && adapterVh.getViewHolder() 464 instanceof PlaybackControlsRowPresenter.ViewHolder) { 465 final Presenter.ViewHolder vh = ((PlaybackControlsRowPresenter.ViewHolder) 466 adapterVh.getViewHolder()).mDescriptionViewHolder; 467 if (vh != null) { 468 vh.view.setAlpha((Float) arg0.getAnimatedValue()); 469 } 470 } 471 } 472 }; 473 474 mDescriptionFadeInAnimator = loadAnimator( 475 getActivity(), R.animator.lb_playback_description_fade_in); 476 mDescriptionFadeInAnimator.addUpdateListener(listener); 477 mDescriptionFadeInAnimator.setInterpolator(mLogDecelerateInterpolator); 478 479 mDescriptionFadeOutAnimator = loadAnimator( 480 getActivity(), R.animator.lb_playback_description_fade_out); 481 mDescriptionFadeOutAnimator.addUpdateListener(listener); 482 } 483 484 private void fade(boolean fadeIn) { 485 if (DEBUG) Log.v(TAG, "fade " + fadeIn); 486 if (getView() == null) { 487 return; 488 } 489 if ((fadeIn && mFadingStatus == IN) || (!fadeIn && mFadingStatus == OUT)) { 490 if (DEBUG) Log.v(TAG, "requested fade in progress"); 491 return; 492 } 493 if ((fadeIn && mBgAlpha == 255) || (!fadeIn && mBgAlpha == 0)) { 494 if (DEBUG) Log.v(TAG, "fade is no-op"); 495 return; 496 } 497 498 mAnimationTranslateY = getVerticalGridView().getSelectedPosition() == 0 ? 499 mMajorFadeTranslateY : mMinorFadeTranslateY; 500 501 if (mFadingStatus == IDLE) { 502 if (fadeIn) { 503 mBgFadeInAnimator.start(); 504 mControlRowFadeInAnimator.start(); 505 mOtherRowFadeInAnimator.start(); 506 mDescriptionFadeInAnimator.start(); 507 } else { 508 mBgFadeOutAnimator.start(); 509 mControlRowFadeOutAnimator.start(); 510 mOtherRowFadeOutAnimator.start(); 511 mDescriptionFadeOutAnimator.start(); 512 } 513 } else { 514 if (fadeIn) { 515 mBgFadeOutAnimator.reverse(); 516 mControlRowFadeOutAnimator.reverse(); 517 mOtherRowFadeOutAnimator.reverse(); 518 mDescriptionFadeOutAnimator.reverse(); 519 } else { 520 mBgFadeInAnimator.reverse(); 521 mControlRowFadeInAnimator.reverse(); 522 mOtherRowFadeInAnimator.reverse(); 523 mDescriptionFadeInAnimator.reverse(); 524 } 525 } 526 527 // If fading in while control row is focused, set initial translationY so 528 // views slide in from below. 529 if (fadeIn && mFadingStatus == IDLE) { 530 final int count = getVerticalGridView().getChildCount(); 531 for (int i = 0; i < count; i++) { 532 getVerticalGridView().getChildAt(i).setTranslationY(mAnimationTranslateY); 533 } 534 } 535 536 mFadingStatus = fadeIn ? IN : OUT; 537 } 538 539 /** 540 * Sets the list of rows for the fragment. 541 */ 542 @Override 543 public void setAdapter(ObjectAdapter adapter) { 544 if (getAdapter() != null) { 545 getAdapter().unregisterObserver(mObserver); 546 } 547 super.setAdapter(adapter); 548 if (adapter != null) { 549 adapter.registerObserver(mObserver); 550 } 551 } 552 553 @Override 554 void setVerticalGridViewLayout(VerticalGridView listview) { 555 if (listview == null) { 556 return; 557 } 558 // Padding affects alignment when last row is focused 559 // (last is first when there's only one row). 560 setBottomPadding(listview, mPaddingBottom); 561 562 // Item alignment affects focused row that isn't the last. 563 listview.setItemAlignmentOffset(mAlignPosition); 564 listview.setItemAlignmentOffsetPercent(100); 565 566 // Push rows to the bottom. 567 listview.setWindowAlignmentOffset(0); 568 listview.setWindowAlignmentOffsetPercent(100); 569 listview.setWindowAlignment(VerticalGridView.WINDOW_ALIGN_HIGH_EDGE); 570 } 571 572 private static void setBottomPadding(View view, int padding) { 573 view.setPadding(view.getPaddingLeft(), view.getPaddingTop(), 574 view.getPaddingRight(), padding); 575 } 576 577 @Override 578 public void onCreate(Bundle savedInstanceState) { 579 super.onCreate(savedInstanceState); 580 581 mAlignPosition = 582 getResources().getDimensionPixelSize(R.dimen.lb_playback_controls_align_bottom); 583 mPaddingBottom = 584 getResources().getDimensionPixelSize(R.dimen.lb_playback_controls_padding_bottom); 585 mBgDarkColor = 586 getResources().getColor(R.color.lb_playback_controls_background_dark); 587 mBgLightColor = 588 getResources().getColor(R.color.lb_playback_controls_background_light); 589 mShowTimeMs = 590 getResources().getInteger(R.integer.lb_playback_controls_show_time_ms); 591 mMajorFadeTranslateY = 592 getResources().getDimensionPixelSize(R.dimen.lb_playback_major_fade_translate_y); 593 mMinorFadeTranslateY = 594 getResources().getDimensionPixelSize(R.dimen.lb_playback_minor_fade_translate_y); 595 596 loadBgAnimator(); 597 loadControlRowAnimator(); 598 loadOtherRowAnimator(); 599 loadDescriptionAnimator(); 600 } 601 602 /** 603 * Sets the background type. 604 * 605 * @param type One of BG_LIGHT, BG_DARK, or BG_NONE. 606 */ 607 public void setBackgroundType(int type) { 608 switch (type) { 609 case BG_LIGHT: 610 case BG_DARK: 611 case BG_NONE: 612 if (type != mBackgroundType) { 613 mBackgroundType = type; 614 updateBackground(); 615 } 616 break; 617 default: 618 throw new IllegalArgumentException("Invalid background type"); 619 } 620 } 621 622 /** 623 * Returns the background type. 624 */ 625 public int getBackgroundType() { 626 return mBackgroundType; 627 } 628 629 private void updateBackground() { 630 if (mRootView != null) { 631 int color = mBgDarkColor; 632 switch (mBackgroundType) { 633 case BG_DARK: break; 634 case BG_LIGHT: color = mBgLightColor; break; 635 case BG_NONE: color = Color.TRANSPARENT; break; 636 } 637 mRootView.setBackground(new ColorDrawable(color)); 638 } 639 } 640 641 private void updateControlsBottomSpace(ItemBridgeAdapter.ViewHolder vh) { 642 // Add extra space between rows 0 and 1 643 if (vh == null && getVerticalGridView() != null) { 644 vh = (ItemBridgeAdapter.ViewHolder) 645 getVerticalGridView().findViewHolderForPosition(0); 646 } 647 if (vh != null && vh.getPresenter() instanceof PlaybackControlsRowPresenter) { 648 final int adapterSize = getAdapter() == null ? 0 : getAdapter().size(); 649 ((PlaybackControlsRowPresenter) vh.getPresenter()).showBottomSpace( 650 (PlaybackControlsRowPresenter.ViewHolder) vh.getViewHolder(), 651 adapterSize > 1); 652 } 653 } 654 655 private final ItemBridgeAdapter.AdapterListener mAdapterListener = 656 new ItemBridgeAdapter.AdapterListener() { 657 @Override 658 public void onAttachedToWindow(ItemBridgeAdapter.ViewHolder vh) { 659 if (DEBUG) Log.v(TAG, "onAttachedToWindow " + vh.getViewHolder().view); 660 if ((mFadingStatus == IDLE && mBgAlpha == 0) || mFadingStatus == OUT) { 661 if (DEBUG) Log.v(TAG, "setting alpha to 0"); 662 vh.getViewHolder().view.setAlpha(0); 663 } 664 if (vh.getPosition() == 0 && mResetControlsToPrimaryActionsPending) { 665 resetControlsToPrimaryActions(vh); 666 } 667 } 668 @Override 669 public void onDetachedFromWindow(ItemBridgeAdapter.ViewHolder vh) { 670 if (DEBUG) Log.v(TAG, "onDetachedFromWindow " + vh.getViewHolder().view); 671 // Reset animation state 672 vh.getViewHolder().view.setAlpha(1f); 673 vh.getViewHolder().view.setTranslationY(0); 674 if (vh.getViewHolder() instanceof PlaybackControlsRowPresenter.ViewHolder) { 675 Presenter.ViewHolder descriptionVh = ((PlaybackControlsRowPresenter.ViewHolder) 676 vh.getViewHolder()).mDescriptionViewHolder; 677 if (descriptionVh != null) { 678 descriptionVh.view.setAlpha(1f); 679 } 680 } 681 } 682 @Override 683 public void onBind(ItemBridgeAdapter.ViewHolder vh) { 684 if (vh.getPosition() == 0) { 685 updateControlsBottomSpace(vh); 686 } 687 } 688 }; 689 690 @Override 691 public View onCreateView(LayoutInflater inflater, ViewGroup container, 692 Bundle savedInstanceState) { 693 mRootView = super.onCreateView(inflater, container, savedInstanceState); 694 mBgAlpha = 255; 695 updateBackground(); 696 getRowsSupportFragment().setExternalAdapterListener(mAdapterListener); 697 return mRootView; 698 } 699 700 @Override 701 public void onDestroyView() { 702 mRootView = null; 703 super.onDestroyView(); 704 } 705 706 private final DataObserver mObserver = new DataObserver() { 707 public void onChanged() { 708 updateControlsBottomSpace(null); 709 } 710 }; 711 712 static abstract class AnimatorListener implements Animator.AnimatorListener { 713 ArrayList<View> mViews = new ArrayList<View>(); 714 ArrayList<Integer> mLayerType = new ArrayList<Integer>(); 715 716 public void onAnimationCancel(Animator animation) { 717 } 718 public void onAnimationRepeat(Animator animation) { 719 } 720 public void onAnimationStart(Animator animation) { 721 getViews(mViews); 722 for (View view : mViews) { 723 mLayerType.add(view.getLayerType()); 724 view.setLayerType(View.LAYER_TYPE_HARDWARE, null); 725 } 726 } 727 public void onAnimationEnd(Animator animation) { 728 for (int i = 0; i < mViews.size(); i++) { 729 mViews.get(i).setLayerType(mLayerType.get(i), null); 730 } 731 mLayerType.clear(); 732 mViews.clear(); 733 } 734 abstract void getViews(ArrayList<View> views); 735 }; 736} 737