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