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