1/* This file is auto-generated from BaseFragment.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.os.Bundle; 19import android.support.v17.leanback.R; 20import android.support.v17.leanback.transition.TransitionHelper; 21import android.support.v17.leanback.transition.TransitionListener; 22import android.view.View; 23import android.view.ViewTreeObserver; 24 25/** 26 * @hide 27 */ 28class BaseSupportFragment extends BrandedSupportFragment { 29 30 private boolean mEntranceTransitionEnabled = false; 31 private boolean mStartEntranceTransitionPending = false; 32 private boolean mEntranceTransitionPreparePending = false; 33 private Object mEntranceTransition; 34 35 static TransitionHelper sTransitionHelper = TransitionHelper.getInstance(); 36 37 @Override 38 public void onViewCreated(View view, Bundle savedInstanceState) { 39 super.onViewCreated(view, savedInstanceState); 40 if (mEntranceTransitionPreparePending) { 41 mEntranceTransitionPreparePending = false; 42 onEntranceTransitionPrepare(); 43 } 44 if (mStartEntranceTransitionPending) { 45 mStartEntranceTransitionPending = false; 46 startEntranceTransition(); 47 } 48 } 49 50 /** 51 * Enables entrance transition.<p> 52 * Entrance transition is the standard slide-in transition that shows rows of data in 53 * browse screen and details screen. 54 * <p> 55 * The method is ignored before LOLLIPOP (API21). 56 * <p> 57 * This method must be called in or 58 * before onCreate(). Typically entrance transition should be enabled when savedInstance is 59 * null so that fragment restored from instanceState does not run an extra entrance transition. 60 * When the entrance transition is enabled, the fragment will make headers and content 61 * hidden initially. 62 * When data of rows are ready, app must call {@link #startEntranceTransition()} to kick off 63 * the transition, otherwise the rows will be invisible forever. 64 * <p> 65 * It is similar to android:windowsEnterTransition and can be considered a late-executed 66 * android:windowsEnterTransition controlled by app. There are two reasons that app needs it: 67 * <li> Workaround the problem that activity transition is not available between launcher and 68 * app. Browse activity must programmatically start the slide-in transition.</li> 69 * <li> Separates DetailsOverviewRow transition from other rows transition. So that 70 * the DetailsOverviewRow transition can be executed earlier without waiting for all rows 71 * to be loaded.</li> 72 * <p> 73 * Transition object is returned by createEntranceTransition(). Typically the app does not need 74 * override the default transition that browse and details provides. 75 */ 76 public void prepareEntranceTransition() { 77 if (TransitionHelper.systemSupportsEntranceTransitions()) { 78 mEntranceTransitionEnabled = true; 79 if (getView() == null) { 80 mEntranceTransitionPreparePending = true; 81 return; 82 } 83 onEntranceTransitionPrepare(); 84 } 85 } 86 87 /** 88 * Return true if entrance transition is enabled and not started yet. 89 * Entrance transition can only be executed once and isEntranceTransitionEnabled() 90 * is reset to false after entrance transition is started. 91 */ 92 boolean isEntranceTransitionEnabled() { 93 return mEntranceTransitionEnabled; 94 } 95 96 /** 97 * Create entrance transition. Subclass can override to load transition from 98 * resource or construct manually. Typically app does not need to 99 * override the default transition that browse and details provides. 100 */ 101 protected Object createEntranceTransition() { 102 return null; 103 } 104 105 /** 106 * Run entrance transition. Subclass may use TransitionManager to perform 107 * go(Scene) or beginDelayedTransition(). App should not override the default 108 * implementation of browse and details fragment. 109 */ 110 protected void runEntranceTransition(Object entranceTransition) { 111 } 112 113 /** 114 * Callback when entrance transition is prepared. This is when fragment should 115 * stop user input and animations. 116 */ 117 protected void onEntranceTransitionPrepare() { 118 } 119 120 /** 121 * Callback when entrance transition is started. This is when fragment should 122 * stop processing layout. 123 */ 124 protected void onEntranceTransitionStart() { 125 } 126 127 /** 128 * Callback when entrance transition is ended. 129 */ 130 protected void onEntranceTransitionEnd() { 131 } 132 133 /** 134 * When fragment finishes loading data, it should call startEntranceTransition() 135 * to execute the entrance transition. 136 * startEntranceTransition() will start transition only if both two conditions 137 * are satisfied: 138 * <li> prepareEntranceTransition() was called.</li> 139 * <li> has not executed entrance transition yet.</li> 140 * <p> 141 * If startEntranceTransition() is called before onViewCreated(), it will be pending 142 * and executed when view is created. 143 */ 144 public void startEntranceTransition() { 145 if (!mEntranceTransitionEnabled || mEntranceTransition != null) { 146 return; 147 } 148 // if view is not created yet, delay until onViewCreated() 149 if (getView() == null) { 150 mStartEntranceTransitionPending = true; 151 return; 152 } 153 if (mEntranceTransitionPreparePending) { 154 mEntranceTransitionPreparePending = false; 155 onEntranceTransitionPrepare(); 156 } 157 // wait till views get their initial position before start transition 158 final View view = getView(); 159 view.getViewTreeObserver().addOnPreDrawListener( 160 new ViewTreeObserver.OnPreDrawListener() { 161 @Override 162 public boolean onPreDraw() { 163 view.getViewTreeObserver().removeOnPreDrawListener(this); 164 internalCreateEntranceTransition(); 165 mEntranceTransitionEnabled = false; 166 if (mEntranceTransition != null) { 167 onEntranceTransitionStart(); 168 runEntranceTransition(mEntranceTransition); 169 } 170 return false; 171 } 172 }); 173 view.invalidate(); 174 } 175 176 void internalCreateEntranceTransition() { 177 mEntranceTransition = createEntranceTransition(); 178 if (mEntranceTransition == null) { 179 return; 180 } 181 sTransitionHelper.setTransitionListener(mEntranceTransition, new TransitionListener() { 182 @Override 183 public void onTransitionEnd(Object transition) { 184 mEntranceTransition = null; 185 onEntranceTransitionEnd(); 186 } 187 }); 188 } 189} 190