1b86a6c2c71514e0cb693597a955e224811b90f96Dake Gu// CHECKSTYLE:OFF Generated code 2b86a6c2c71514e0cb693597a955e224811b90f96Dake Gu/* This file is auto-generated from {}DetailsSupportFragmentBackgroundController.java. DO NOT MODIFY. */ 3b86a6c2c71514e0cb693597a955e224811b90f96Dake Gu 4e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu/* 5e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * Copyright (C) 2017 The Android Open Source Project 6e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * 7e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * Licensed under the Apache License, Version 2.0 (the "License"); 8e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * you may not use this file except in compliance with the License. 9e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * You may obtain a copy of the License at 10e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * 11e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * http://www.apache.org/licenses/LICENSE-2.0 12e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * 13e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * Unless required by applicable law or agreed to in writing, software 14e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * distributed under the License is distributed on an "AS IS" BASIS, 15e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * See the License for the specific language governing permissions and 17e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * limitations under the License. 18e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu */ 19e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gupackage android.support.v17.leanback.app; 20e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu 21e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Guimport android.animation.PropertyValuesHolder; 22e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Guimport android.graphics.Bitmap; 23e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Guimport android.graphics.Color; 24e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Guimport android.graphics.drawable.ColorDrawable; 25e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Guimport android.graphics.drawable.Drawable; 26e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Guimport android.support.annotation.ColorInt; 27e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Guimport android.support.annotation.NonNull; 28e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Guimport android.support.annotation.Nullable; 29e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Guimport android.support.v17.leanback.R; 30e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Guimport android.support.v17.leanback.graphics.FitWidthBitmapDrawable; 31e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Guimport android.support.v17.leanback.media.PlaybackGlue; 32e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Guimport android.support.v17.leanback.media.PlaybackGlueHost; 33e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Guimport android.support.v17.leanback.widget.DetailsParallaxDrawable; 34e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Guimport android.support.v17.leanback.widget.ParallaxTarget; 35b86a6c2c71514e0cb693597a955e224811b90f96Dake Guimport android.app.Fragment; 36e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu 37e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu/** 38e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * Controller for DetailsFragment parallax background and embedded video play. 39e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * <p> 40e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * The parallax background drawable is made of two parts: cover drawable (by default 41e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * {@link FitWidthBitmapDrawable}) above the details overview row and bottom drawable (by default 42e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * {@link ColorDrawable}) below the details overview row. While vertically scrolling rows, the size 43e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * of cover drawable and bottom drawable will be updated and the cover drawable will by default 44e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * perform a parallax shift using {@link FitWidthBitmapDrawable#PROPERTY_VERTICAL_OFFSET}. 45e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * </p> 46e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * <pre> 47e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * *************************** 48e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * * Cover Drawable * 49e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * * (FitWidthBitmapDrawable)* 50e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * * * 51e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * *************************** 52e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * * DetailsOverviewRow * 53e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * * * 54e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * *************************** 55e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * * Bottom Drawable * 56e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * * (ColorDrawable) * 57e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * * Related * 58e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * * Content * 59e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * *************************** 60e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * </pre> 61e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * Both parallax background drawable and embedded video play are optional. App must call 62e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * {@link #enableParallax()} and/or {@link #setupVideoPlayback(PlaybackGlue)} explicitly. 63e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * The PlaybackGlue is automatically {@link PlaybackGlue#play()} when fragment starts and 64e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * {@link PlaybackGlue#pause()} when fragment stops. When video is ready to play, cover drawable 65e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * will be faded out. 66e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * Example: 67e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * <pre> 68e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * DetailsFragmentBackgroundController mController = new DetailsFragmentBackgroundController(this); 69e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * 70e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * public void onCreate(Bundle savedInstance) { 71e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * super.onCreate(savedInstance); 72e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * MediaPlayerGlue player = new MediaPlayerGlue(..); 73e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * player.setUrl(...); 74e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * mController.enableParallax(); 75e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * mController.setupVideoPlayback(player); 76e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * } 77e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * 78e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * static class MyLoadBitmapTask extends ... { 79e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * WeakReference<MyFragment> mFragmentRef; 80e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * MyLoadBitmapTask(MyFragment fragment) { 81e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * mFragmentRef = new WeakReference(fragment); 82e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * } 83e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * protected void onPostExecute(Bitmap bitmap) { 84e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * MyFragment fragment = mFragmentRef.get(); 85e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * if (fragment != null) { 86e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * fragment.mController.setCoverBitmap(bitmap); 87e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * } 88e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * } 89e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * } 90e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * 91e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * public void onStart() { 92e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * new MyLoadBitmapTask(this).execute(url); 93e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * } 94e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * 95e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * public void onStop() { 96e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * mController.setCoverBitmap(null); 97e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * } 98e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * </pre> 99e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * <p> 100e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * To customize cover drawable and/or bottom drawable, app should call 101e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * {@link #enableParallax(Drawable, Drawable, ParallaxTarget.PropertyValuesHolderTarget)}. 102e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * If app supplies a custom cover Drawable, it should not call {@link #setCoverBitmap(Bitmap)}. 103e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * If app supplies a custom bottom Drawable, it should not call {@link #setSolidColor(int)}. 104e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * </p> 105e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * <p> 106e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * To customize playback fragment, app should override {@link #onCreateVideoFragment()} and 107e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * {@link #onCreateGlueHost()}. 108e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * </p> 109e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * 110e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu */ 111e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gupublic class DetailsFragmentBackgroundController { 112e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu 113f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu final DetailsFragment mFragment; 114f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu DetailsParallaxDrawable mParallaxDrawable; 115f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu int mParallaxDrawableMaxOffset; 116f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu PlaybackGlue mPlaybackGlue; 117f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu DetailsBackgroundVideoHelper mVideoHelper; 118f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu Bitmap mCoverBitmap; 119f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu int mSolidColor; 120f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu boolean mCanUseHost = false; 1213bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu boolean mInitialControlVisible = false; 122e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu 123c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin private Fragment mLastVideoFragmentForGlueHost; 124c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin 125e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu /** 126e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * Creates a DetailsFragmentBackgroundController for a DetailsFragment. Note that 127e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * each DetailsFragment can only associate with one DetailsFragmentBackgroundController. 128e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * 129e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * @param fragment The DetailsFragment to control background and embedded video playing. 130e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * @throws IllegalStateException If fragment was already associated with another controller. 131e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu */ 132e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu public DetailsFragmentBackgroundController(DetailsFragment fragment) { 133e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu if (fragment.mDetailsBackgroundController != null) { 134e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu throw new IllegalStateException("Each DetailsFragment is allowed to initialize " 135e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu + "DetailsFragmentBackgroundController once"); 136e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu } 137e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu fragment.mDetailsBackgroundController = this; 138e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu mFragment = fragment; 139e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu } 140e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu 141e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu /** 142e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * Enables default parallax background using a {@link FitWidthBitmapDrawable} as cover drawable 143e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * and {@link ColorDrawable} as bottom drawable. A vertical parallax movement will be applied 144e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * to the FitWidthBitmapDrawable. App may use {@link #setSolidColor(int)} and 145e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * {@link #setCoverBitmap(Bitmap)} to change the content of bottom drawable and cover drawable. 146e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * This method must be called before {@link #setupVideoPlayback(PlaybackGlue)}. 147e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * 148e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * @see #setCoverBitmap(Bitmap) 149e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * @see #setSolidColor(int) 150e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * @throws IllegalStateException If {@link #setupVideoPlayback(PlaybackGlue)} was called. 151e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu */ 152e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu public void enableParallax() { 153e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu int offset = mParallaxDrawableMaxOffset; 154e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu if (offset == 0) { 155e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu offset = FragmentUtil.getContext(mFragment).getResources() 156e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu .getDimensionPixelSize(R.dimen.lb_details_cover_drawable_parallax_movement); 157e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu } 158e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu Drawable coverDrawable = new FitWidthBitmapDrawable(); 159e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu ColorDrawable colorDrawable = new ColorDrawable(); 160e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu enableParallax(coverDrawable, colorDrawable, 161e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu new ParallaxTarget.PropertyValuesHolderTarget( 162e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu coverDrawable, 163e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu PropertyValuesHolder.ofInt(FitWidthBitmapDrawable.PROPERTY_VERTICAL_OFFSET, 164e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu 0, -offset) 165e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu )); 166e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu } 167e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu 168e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu /** 169e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * Enables parallax background using a custom cover drawable at top and a custom bottom 170e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * drawable. This method must be called before {@link #setupVideoPlayback(PlaybackGlue)}. 171e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * 172e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * @param coverDrawable Custom cover drawable shown at top. {@link #setCoverBitmap(Bitmap)} 173e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * will not work if coverDrawable is not {@link FitWidthBitmapDrawable}; 174e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * in that case it's app's responsibility to set content into 175e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * coverDrawable. 176e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * @param bottomDrawable Drawable shown at bottom. {@link #setSolidColor(int)} will not work 177e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * if bottomDrawable is not {@link ColorDrawable}; in that case it's app's 178e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * responsibility to set content of bottomDrawable. 179e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * @param coverDrawableParallaxTarget Target to perform parallax effect within coverDrawable. 180e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * Use null for no parallax movement effect. 181e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * Example to move bitmap within FitWidthBitmapDrawable: 182e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * new ParallaxTarget.PropertyValuesHolderTarget( 183e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * coverDrawable, PropertyValuesHolder.ofInt( 184e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * FitWidthBitmapDrawable.PROPERTY_VERTICAL_OFFSET, 185e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * 0, -120)) 186e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * @throws IllegalStateException If {@link #setupVideoPlayback(PlaybackGlue)} was called. 187e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu */ 188e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu public void enableParallax(@NonNull Drawable coverDrawable, @NonNull Drawable bottomDrawable, 189e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu @Nullable ParallaxTarget.PropertyValuesHolderTarget 190e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu coverDrawableParallaxTarget) { 191e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu if (mParallaxDrawable != null) { 192e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu return; 193e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu } 194e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu // if bitmap is set before enableParallax, use it as initial value. 195e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu if (mCoverBitmap != null && coverDrawable instanceof FitWidthBitmapDrawable) { 196e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu ((FitWidthBitmapDrawable) coverDrawable).setBitmap(mCoverBitmap); 197e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu } 198e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu // if solid color is set before enableParallax, use it as initial value. 199e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu if (mSolidColor != Color.TRANSPARENT && bottomDrawable instanceof ColorDrawable) { 200e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu ((ColorDrawable) bottomDrawable).setColor(mSolidColor); 201e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu } 202e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu if (mPlaybackGlue != null) { 203e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu throw new IllegalStateException("enableParallaxDrawable must be called before " 204e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu + "enableVideoPlayback"); 205e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu } 206e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu mParallaxDrawable = new DetailsParallaxDrawable( 207e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu FragmentUtil.getContext(mFragment), 208e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu mFragment.getParallax(), 209e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu coverDrawable, 210e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu bottomDrawable, 211e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu coverDrawableParallaxTarget); 212e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu mFragment.setBackgroundDrawable(mParallaxDrawable); 21389097f67f988ebba714a95e10369665280db0c27Dake Gu // create a VideoHelper with null PlaybackGlue for changing CoverDrawable visibility 21489097f67f988ebba714a95e10369665280db0c27Dake Gu // before PlaybackGlue is ready. 21589097f67f988ebba714a95e10369665280db0c27Dake Gu mVideoHelper = new DetailsBackgroundVideoHelper(null, 21689097f67f988ebba714a95e10369665280db0c27Dake Gu mFragment.getParallax(), mParallaxDrawable.getCoverDrawable()); 217e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu } 218e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu 219e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu /** 220e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * Enable video playback and set proper {@link PlaybackGlueHost}. This method by default 221e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * creates a VideoFragment and VideoFragmentGlueHost to host the PlaybackGlue. 222f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu * This method must be called after calling details Fragment super.onCreate(). This method 223f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu * can be called multiple times to replace existing PlaybackGlue or calling 224f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu * setupVideoPlayback(null) to clear. Note a typical {@link PlaybackGlue} subclass releases 225f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu * resources in {@link PlaybackGlue#onDetachedFromHost()}, when the {@link PlaybackGlue} 226f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu * subclass is not doing that, it's app's responsibility to release the resources. 227e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * 228f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu * @param playbackGlue The new PlaybackGlue to set as background or null to clear existing one. 229e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * @see #onCreateVideoFragment() 230e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * @see #onCreateGlueHost(). 231e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu */ 23276c53f6a2152d31a255a36276ada145be5ec474aDake Gu @SuppressWarnings("ReferenceEquality") 233e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu public void setupVideoPlayback(@NonNull PlaybackGlue playbackGlue) { 23401f4dd4a9bc3b80d3ddecc0264facbf6abfc1cc3Dake Gu if (mPlaybackGlue == playbackGlue) { 23501f4dd4a9bc3b80d3ddecc0264facbf6abfc1cc3Dake Gu return; 23601f4dd4a9bc3b80d3ddecc0264facbf6abfc1cc3Dake Gu } 237c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin 238c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin PlaybackGlueHost playbackGlueHost = null; 239f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu if (mPlaybackGlue != null) { 240c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin playbackGlueHost = mPlaybackGlue.getHost(); 241f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu mPlaybackGlue.setHost(null); 242f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu } 243c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin 244e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu mPlaybackGlue = playbackGlue; 24589097f67f988ebba714a95e10369665280db0c27Dake Gu mVideoHelper.setPlaybackGlue(mPlaybackGlue); 246f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu if (mCanUseHost && mPlaybackGlue != null) { 247c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin if (playbackGlueHost == null 248c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin || mLastVideoFragmentForGlueHost != findOrCreateVideoFragment()) { 2493bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu mPlaybackGlue.setHost(createGlueHost()); 250c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin mLastVideoFragmentForGlueHost = findOrCreateVideoFragment(); 251c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin } else { 252c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin mPlaybackGlue.setHost(playbackGlueHost); 253c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin } 25401f4dd4a9bc3b80d3ddecc0264facbf6abfc1cc3Dake Gu } 25501f4dd4a9bc3b80d3ddecc0264facbf6abfc1cc3Dake Gu } 25601f4dd4a9bc3b80d3ddecc0264facbf6abfc1cc3Dake Gu 25701f4dd4a9bc3b80d3ddecc0264facbf6abfc1cc3Dake Gu /** 258f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu * Returns current PlaybackGlue or null if not set or cleared. 259f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu * 260f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu * @return Current PlaybackGlue or null 261f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu */ 262f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu public final PlaybackGlue getPlaybackGlue() { 263f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu return mPlaybackGlue; 264f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu } 265f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu 266f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu /** 267f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu * Precondition allows user navigate to video fragment using DPAD. Default implementation 268f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu * returns true if PlaybackGlue is not null. Subclass may override, e.g. only allow navigation 2693bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * when {@link PlaybackGlue#isPrepared()} is true. Note this method does not block 270f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu * app calls {@link #switchToVideo}. 271f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu * 272f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu * @return True allow to navigate to video fragment. 273f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu */ 274f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu public boolean canNavigateToVideoFragment() { 275f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu return mPlaybackGlue != null; 276f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu } 277f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu 2783bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu void switchToVideoBeforeCreate() { 2793bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu mVideoHelper.crossFadeBackgroundToVideo(true, true); 2803bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu mInitialControlVisible = true; 28189097f67f988ebba714a95e10369665280db0c27Dake Gu } 28289097f67f988ebba714a95e10369665280db0c27Dake Gu 283f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu /** 284f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu * Switch to video fragment, note that this method is not affected by result of 28589097f67f988ebba714a95e10369665280db0c27Dake Gu * {@link #canNavigateToVideoFragment()}. If the method is called in DetailsFragment.onCreate() 28689097f67f988ebba714a95e10369665280db0c27Dake Gu * it will make video fragment to be initially focused once it is created. 28789097f67f988ebba714a95e10369665280db0c27Dake Gu * <p> 28889097f67f988ebba714a95e10369665280db0c27Dake Gu * Calling switchToVideo() in DetailsFragment.onCreate() will clear the activity enter 28989097f67f988ebba714a95e10369665280db0c27Dake Gu * transition and shared element transition. 29089097f67f988ebba714a95e10369665280db0c27Dake Gu * </p> 29189097f67f988ebba714a95e10369665280db0c27Dake Gu * <p> 29289097f67f988ebba714a95e10369665280db0c27Dake Gu * If switchToVideo() is called after {@link DetailsFragment#prepareEntranceTransition()} and 29389097f67f988ebba714a95e10369665280db0c27Dake Gu * before {@link DetailsFragment#onEntranceTransitionEnd()}, it will be ignored. 29489097f67f988ebba714a95e10369665280db0c27Dake Gu * </p> 29589097f67f988ebba714a95e10369665280db0c27Dake Gu * <p> 29689097f67f988ebba714a95e10369665280db0c27Dake Gu * If {@link DetailsFragment#prepareEntranceTransition()} is called after switchToVideo(), an 29789097f67f988ebba714a95e10369665280db0c27Dake Gu * IllegalStateException will be thrown. 29889097f67f988ebba714a95e10369665280db0c27Dake Gu * </p> 299f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu */ 300f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu public final void switchToVideo() { 30189097f67f988ebba714a95e10369665280db0c27Dake Gu mFragment.switchToVideo(); 302f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu } 303f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu 304f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu /** 305f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu * Switch to rows fragment. 306f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu */ 307f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu public final void switchToRows() { 30889097f67f988ebba714a95e10369665280db0c27Dake Gu mFragment.switchToRows(); 309f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu } 310f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu 311f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu /** 312f37579e64940bfdd642cc315f6347d60b5addd69Dake Gu * When fragment is started and no running transition. First set host if not yet set, second 313f37579e64940bfdd642cc315f6347d60b5addd69Dake Gu * start playing if it was paused before. 31401f4dd4a9bc3b80d3ddecc0264facbf6abfc1cc3Dake Gu */ 315f37579e64940bfdd642cc315f6347d60b5addd69Dake Gu void onStart() { 31601f4dd4a9bc3b80d3ddecc0264facbf6abfc1cc3Dake Gu if (!mCanUseHost) { 31701f4dd4a9bc3b80d3ddecc0264facbf6abfc1cc3Dake Gu mCanUseHost = true; 31801f4dd4a9bc3b80d3ddecc0264facbf6abfc1cc3Dake Gu if (mPlaybackGlue != null) { 3193bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu mPlaybackGlue.setHost(createGlueHost()); 320c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin mLastVideoFragmentForGlueHost = findOrCreateVideoFragment(); 32101f4dd4a9bc3b80d3ddecc0264facbf6abfc1cc3Dake Gu } 32201f4dd4a9bc3b80d3ddecc0264facbf6abfc1cc3Dake Gu } 3233bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu if (mPlaybackGlue != null && mPlaybackGlue.isPrepared()) { 3243961cea270f51c29433a7eb21ec5f8c9ca7bd7d7Dake Gu mPlaybackGlue.play(); 3253961cea270f51c29433a7eb21ec5f8c9ca7bd7d7Dake Gu } 3263961cea270f51c29433a7eb21ec5f8c9ca7bd7d7Dake Gu } 3273961cea270f51c29433a7eb21ec5f8c9ca7bd7d7Dake Gu 3283961cea270f51c29433a7eb21ec5f8c9ca7bd7d7Dake Gu void onStop() { 3293961cea270f51c29433a7eb21ec5f8c9ca7bd7d7Dake Gu if (mPlaybackGlue != null) { 3303961cea270f51c29433a7eb21ec5f8c9ca7bd7d7Dake Gu mPlaybackGlue.pause(); 3313961cea270f51c29433a7eb21ec5f8c9ca7bd7d7Dake Gu } 33201f4dd4a9bc3b80d3ddecc0264facbf6abfc1cc3Dake Gu } 33301f4dd4a9bc3b80d3ddecc0264facbf6abfc1cc3Dake Gu 33401f4dd4a9bc3b80d3ddecc0264facbf6abfc1cc3Dake Gu /** 33501f4dd4a9bc3b80d3ddecc0264facbf6abfc1cc3Dake Gu * Disable parallax that would auto-start video playback 33601f4dd4a9bc3b80d3ddecc0264facbf6abfc1cc3Dake Gu * @return true if video fragment is visible or false otherwise. 33701f4dd4a9bc3b80d3ddecc0264facbf6abfc1cc3Dake Gu */ 33801f4dd4a9bc3b80d3ddecc0264facbf6abfc1cc3Dake Gu boolean disableVideoParallax() { 33901f4dd4a9bc3b80d3ddecc0264facbf6abfc1cc3Dake Gu if (mVideoHelper != null) { 34001f4dd4a9bc3b80d3ddecc0264facbf6abfc1cc3Dake Gu mVideoHelper.stopParallax(); 34101f4dd4a9bc3b80d3ddecc0264facbf6abfc1cc3Dake Gu return mVideoHelper.isVideoVisible(); 34201f4dd4a9bc3b80d3ddecc0264facbf6abfc1cc3Dake Gu } 34301f4dd4a9bc3b80d3ddecc0264facbf6abfc1cc3Dake Gu return false; 344e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu } 345e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu 346e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu /** 347e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * Returns the cover drawable at top. Returns null if {@link #enableParallax()} is not called. 348e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * By default it's a {@link FitWidthBitmapDrawable}. 349e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * 350e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * @return The cover drawable at top. 351e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu */ 352e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu public final Drawable getCoverDrawable() { 353e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu if (mParallaxDrawable == null) { 354e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu return null; 355e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu } 356e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu return mParallaxDrawable.getCoverDrawable(); 357e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu } 358e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu 359e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu /** 360e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * Returns the drawable at bottom. Returns null if {@link #enableParallax()} is not called. 361e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * By default it's a {@link ColorDrawable}. 362e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * 363e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * @return The bottom drawable. 364e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu */ 365e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu public final Drawable getBottomDrawable() { 366e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu if (mParallaxDrawable == null) { 367e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu return null; 368e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu } 369e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu return mParallaxDrawable.getBottomDrawable(); 370e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu } 371e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu 372e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu /** 373e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * Creates a Fragment to host {@link PlaybackGlue}. Returns a new {@link VideoFragment} by 374e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * default. App may override and return a different fragment and it also must override 375e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * {@link #onCreateGlueHost()}. 376e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * 377e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * @return A new fragment used in {@link #onCreateGlueHost()}. 378e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * @see #onCreateGlueHost() 379e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * @see #setupVideoPlayback(PlaybackGlue) 380e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu */ 381e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu public Fragment onCreateVideoFragment() { 382e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu return new VideoFragment(); 383e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu } 384e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu 385e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu /** 386e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * Creates a PlaybackGlueHost to host PlaybackGlue. App may override this if it overrides 387e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * {@link #onCreateVideoFragment()}. This method must be called after calling Fragment 388e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * super.onCreate(). When override this method, app may call 389e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * {@link #findOrCreateVideoFragment()} to get or create a fragment. 390e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * 391e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * @return A new PlaybackGlueHost to host PlaybackGlue. 392e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * @see #onCreateVideoFragment() 393e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * @see #findOrCreateVideoFragment() 394e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * @see #setupVideoPlayback(PlaybackGlue) 395e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu */ 396e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu public PlaybackGlueHost onCreateGlueHost() { 397e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu return new VideoFragmentGlueHost((VideoFragment) findOrCreateVideoFragment()); 398e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu } 399e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu 4003bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu PlaybackGlueHost createGlueHost() { 4013bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu PlaybackGlueHost host = onCreateGlueHost(); 4023bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu if (mInitialControlVisible) { 4033bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu host.showControlsOverlay(false); 4043bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu } else { 4053bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu host.hideControlsOverlay(false); 4063bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu } 4073bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu return host; 4083bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu } 4093bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu 410e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu /** 411e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * Adds or gets fragment for rendering video in DetailsFragment. A subclass that 412e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * overrides {@link #onCreateGlueHost()} should call this method to get a fragment for creating 413e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * a {@link PlaybackGlueHost}. 414e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * 415e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * @return Fragment the added or restored fragment responsible for rendering video. 416e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * @see #onCreateGlueHost() 417e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu */ 418e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu public final Fragment findOrCreateVideoFragment() { 419e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu return mFragment.findOrCreateVideoFragment(); 420e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu } 421e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu 422e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu /** 423e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * Convenient method to set Bitmap in cover drawable. If app is not using default 424e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * {@link FitWidthBitmapDrawable}, app should not use this method It's safe to call 425e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * setCoverBitmap() before calling {@link #enableParallax()}. 426e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * 427e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * @param bitmap bitmap to set as cover. 428e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu */ 429e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu public final void setCoverBitmap(Bitmap bitmap) { 430e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu mCoverBitmap = bitmap; 431e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu Drawable drawable = getCoverDrawable(); 432e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu if (drawable instanceof FitWidthBitmapDrawable) { 433e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu ((FitWidthBitmapDrawable) drawable).setBitmap(mCoverBitmap); 434e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu } 435e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu } 436e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu 437e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu /** 438e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * Returns Bitmap set by {@link #setCoverBitmap(Bitmap)}. 439e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * 440e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * @return Bitmap for cover drawable. 441e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu */ 442e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu public final Bitmap getCoverBitmap() { 443e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu return mCoverBitmap; 444e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu } 445e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu 446e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu /** 447e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * Returns color set by {@link #setSolidColor(int)}. 448e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * 449e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * @return Solid color used for bottom drawable. 450e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu */ 451e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu public final @ColorInt int getSolidColor() { 452e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu return mSolidColor; 453e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu } 454e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu 455e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu /** 456e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * Convenient method to set color in bottom drawable. If app is not using default 457e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * {@link ColorDrawable}, app should not use this method. It's safe to call setSolidColor() 458e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * before calling {@link #enableParallax()}. 459e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * 460e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * @param color color for bottom drawable. 461e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu */ 462e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu public final void setSolidColor(@ColorInt int color) { 463e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu mSolidColor = color; 464e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu Drawable bottomDrawable = getBottomDrawable(); 465e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu if (bottomDrawable instanceof ColorDrawable) { 466e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu ((ColorDrawable) bottomDrawable).setColor(color); 467e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu } 468e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu } 469e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu 470e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu /** 471e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * Sets default parallax offset in pixels for bitmap moving vertically. This method must 472e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * be called before {@link #enableParallax()}. 473e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * 474e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * @param offset Offset in pixels (e.g. 120). 475e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * @see #enableParallax() 476e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu */ 477e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu public final void setParallaxDrawableMaxOffset(int offset) { 478e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu if (mParallaxDrawable != null) { 479e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu throw new IllegalStateException("enableParallax already called"); 480e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu } 481e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu mParallaxDrawableMaxOffset = offset; 482e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu } 483e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu 484e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu /** 485e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * Returns Default parallax offset in pixels for bitmap moving vertically. 486e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * When 0, a default value would be used. 487e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * 488e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * @return Default parallax offset in pixels for bitmap moving vertically. 489e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * @see #enableParallax() 490e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu */ 491e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu public final int getParallaxDrawableMaxOffset() { 492e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu return mParallaxDrawableMaxOffset; 493e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu } 494e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu 495e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu} 496