1// CHECKSTYLE:OFF Generated code 2/* This file is auto-generated from BaseSupportFragment.java. DO NOT MODIFY. */ 3 4/* 5 * Copyright (C) 2014 The Android Open Source Project 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 8 * in compliance with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software distributed under the License 13 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 14 * or implied. See the License for the specific language governing permissions and limitations under 15 * the License. 16 */ 17package android.support.v17.leanback.app; 18 19import android.annotation.SuppressLint; 20import android.os.Bundle; 21import android.support.v17.leanback.transition.TransitionHelper; 22import android.support.v17.leanback.transition.TransitionListener; 23import android.support.v17.leanback.util.StateMachine; 24import android.support.v17.leanback.util.StateMachine.Condition; 25import android.support.v17.leanback.util.StateMachine.Event; 26import android.support.v17.leanback.util.StateMachine.State; 27import android.view.View; 28import android.view.ViewTreeObserver; 29 30/** 31 * Base class for leanback Fragments. This class is not intended to be subclassed by apps. 32 */ 33@SuppressWarnings("FragmentNotInstantiable") 34public class BaseFragment extends BrandedFragment { 35 36 /** 37 * The start state for all 38 */ 39 final State STATE_START = new State("START", true, false); 40 41 /** 42 * Initial State for ENTRNACE transition. 43 */ 44 final State STATE_ENTRANCE_INIT = new State("ENTRANCE_INIT"); 45 46 /** 47 * prepareEntranceTransition is just called, but view not ready yet. We can enable the 48 * busy spinner. 49 */ 50 final State STATE_ENTRANCE_ON_PREPARED = new State("ENTRANCE_ON_PREPARED", true, false) { 51 @Override 52 public void run() { 53 mProgressBarManager.show(); 54 } 55 }; 56 57 /** 58 * prepareEntranceTransition is called and main content view to slide in was created, so we can 59 * call {@link #onEntranceTransitionPrepare}. Note that we dont set initial content to invisible 60 * in this State, the process is very different in subclass, e.g. BrowseFragment hide header 61 * views and hide main fragment view in two steps. 62 */ 63 final State STATE_ENTRANCE_ON_PREPARED_ON_CREATEVIEW = new State( 64 "ENTRANCE_ON_PREPARED_ON_CREATEVIEW") { 65 @Override 66 public void run() { 67 onEntranceTransitionPrepare(); 68 } 69 }; 70 71 /** 72 * execute the entrance transition. 73 */ 74 final State STATE_ENTRANCE_PERFORM = new State("STATE_ENTRANCE_PERFORM") { 75 @Override 76 public void run() { 77 mProgressBarManager.hide(); 78 onExecuteEntranceTransition(); 79 } 80 }; 81 82 /** 83 * execute onEntranceTransitionEnd. 84 */ 85 final State STATE_ENTRANCE_ON_ENDED = new State("ENTRANCE_ON_ENDED") { 86 @Override 87 public void run() { 88 onEntranceTransitionEnd(); 89 } 90 }; 91 92 /** 93 * either entrance transition completed or skipped 94 */ 95 final State STATE_ENTRANCE_COMPLETE = new State("ENTRANCE_COMPLETE", true, false); 96 97 /** 98 * Event fragment.onCreate() 99 */ 100 final Event EVT_ON_CREATE = new Event("onCreate"); 101 102 /** 103 * Event fragment.onViewCreated() 104 */ 105 final Event EVT_ON_CREATEVIEW = new Event("onCreateView"); 106 107 /** 108 * Event for {@link #prepareEntranceTransition()} is called. 109 */ 110 final Event EVT_PREPARE_ENTRANCE = new Event("prepareEntranceTransition"); 111 112 /** 113 * Event for {@link #startEntranceTransition()} is called. 114 */ 115 final Event EVT_START_ENTRANCE = new Event("startEntranceTransition"); 116 117 /** 118 * Event for entrance transition is ended through Transition listener. 119 */ 120 final Event EVT_ENTRANCE_END = new Event("onEntranceTransitionEnd"); 121 122 /** 123 * Event for skipping entrance transition if not supported. 124 */ 125 final Condition COND_TRANSITION_NOT_SUPPORTED = new Condition("EntranceTransitionNotSupport") { 126 @Override 127 public boolean canProceed() { 128 return !TransitionHelper.systemSupportsEntranceTransitions(); 129 } 130 }; 131 132 final StateMachine mStateMachine = new StateMachine(); 133 134 Object mEntranceTransition; 135 final ProgressBarManager mProgressBarManager = new ProgressBarManager(); 136 137 @SuppressLint("ValidFragment") 138 BaseFragment() { 139 } 140 141 @Override 142 public void onCreate(Bundle savedInstanceState) { 143 createStateMachineStates(); 144 createStateMachineTransitions(); 145 mStateMachine.start(); 146 super.onCreate(savedInstanceState); 147 mStateMachine.fireEvent(EVT_ON_CREATE); 148 } 149 150 void createStateMachineStates() { 151 mStateMachine.addState(STATE_START); 152 mStateMachine.addState(STATE_ENTRANCE_INIT); 153 mStateMachine.addState(STATE_ENTRANCE_ON_PREPARED); 154 mStateMachine.addState(STATE_ENTRANCE_ON_PREPARED_ON_CREATEVIEW); 155 mStateMachine.addState(STATE_ENTRANCE_PERFORM); 156 mStateMachine.addState(STATE_ENTRANCE_ON_ENDED); 157 mStateMachine.addState(STATE_ENTRANCE_COMPLETE); 158 } 159 160 void createStateMachineTransitions() { 161 mStateMachine.addTransition(STATE_START, STATE_ENTRANCE_INIT, EVT_ON_CREATE); 162 mStateMachine.addTransition(STATE_ENTRANCE_INIT, STATE_ENTRANCE_COMPLETE, 163 COND_TRANSITION_NOT_SUPPORTED); 164 mStateMachine.addTransition(STATE_ENTRANCE_INIT, STATE_ENTRANCE_COMPLETE, 165 EVT_ON_CREATEVIEW); 166 mStateMachine.addTransition(STATE_ENTRANCE_INIT, STATE_ENTRANCE_ON_PREPARED, 167 EVT_PREPARE_ENTRANCE); 168 mStateMachine.addTransition(STATE_ENTRANCE_ON_PREPARED, 169 STATE_ENTRANCE_ON_PREPARED_ON_CREATEVIEW, 170 EVT_ON_CREATEVIEW); 171 mStateMachine.addTransition(STATE_ENTRANCE_ON_PREPARED, 172 STATE_ENTRANCE_PERFORM, 173 EVT_START_ENTRANCE); 174 mStateMachine.addTransition(STATE_ENTRANCE_ON_PREPARED_ON_CREATEVIEW, 175 STATE_ENTRANCE_PERFORM); 176 mStateMachine.addTransition(STATE_ENTRANCE_PERFORM, 177 STATE_ENTRANCE_ON_ENDED, 178 EVT_ENTRANCE_END); 179 mStateMachine.addTransition(STATE_ENTRANCE_ON_ENDED, STATE_ENTRANCE_COMPLETE); 180 } 181 182 @Override 183 public void onViewCreated(View view, Bundle savedInstanceState) { 184 super.onViewCreated(view, savedInstanceState); 185 mStateMachine.fireEvent(EVT_ON_CREATEVIEW); 186 } 187 188 /** 189 * Enables entrance transition.<p> 190 * Entrance transition is the standard slide-in transition that shows rows of data in 191 * browse screen and details screen. 192 * <p> 193 * The method is ignored before LOLLIPOP (API21). 194 * <p> 195 * This method must be called in or 196 * before onCreate(). Typically entrance transition should be enabled when savedInstance is 197 * null so that fragment restored from instanceState does not run an extra entrance transition. 198 * When the entrance transition is enabled, the fragment will make headers and content 199 * hidden initially. 200 * When data of rows are ready, app must call {@link #startEntranceTransition()} to kick off 201 * the transition, otherwise the rows will be invisible forever. 202 * <p> 203 * It is similar to android:windowsEnterTransition and can be considered a late-executed 204 * android:windowsEnterTransition controlled by app. There are two reasons that app needs it: 205 * <li> Workaround the problem that activity transition is not available between launcher and 206 * app. Browse activity must programmatically start the slide-in transition.</li> 207 * <li> Separates DetailsOverviewRow transition from other rows transition. So that 208 * the DetailsOverviewRow transition can be executed earlier without waiting for all rows 209 * to be loaded.</li> 210 * <p> 211 * Transition object is returned by createEntranceTransition(). Typically the app does not need 212 * override the default transition that browse and details provides. 213 */ 214 public void prepareEntranceTransition() { 215 mStateMachine.fireEvent(EVT_PREPARE_ENTRANCE); 216 } 217 218 /** 219 * Create entrance transition. Subclass can override to load transition from 220 * resource or construct manually. Typically app does not need to 221 * override the default transition that browse and details provides. 222 */ 223 protected Object createEntranceTransition() { 224 return null; 225 } 226 227 /** 228 * Run entrance transition. Subclass may use TransitionManager to perform 229 * go(Scene) or beginDelayedTransition(). App should not override the default 230 * implementation of browse and details fragment. 231 */ 232 protected void runEntranceTransition(Object entranceTransition) { 233 } 234 235 /** 236 * Callback when entrance transition is prepared. This is when fragment should 237 * stop user input and animations. 238 */ 239 protected void onEntranceTransitionPrepare() { 240 } 241 242 /** 243 * Callback when entrance transition is started. This is when fragment should 244 * stop processing layout. 245 */ 246 protected void onEntranceTransitionStart() { 247 } 248 249 /** 250 * Callback when entrance transition is ended. 251 */ 252 protected void onEntranceTransitionEnd() { 253 } 254 255 /** 256 * When fragment finishes loading data, it should call startEntranceTransition() 257 * to execute the entrance transition. 258 * startEntranceTransition() will start transition only if both two conditions 259 * are satisfied: 260 * <li> prepareEntranceTransition() was called.</li> 261 * <li> has not executed entrance transition yet.</li> 262 * <p> 263 * If startEntranceTransition() is called before onViewCreated(), it will be pending 264 * and executed when view is created. 265 */ 266 public void startEntranceTransition() { 267 mStateMachine.fireEvent(EVT_START_ENTRANCE); 268 } 269 270 void onExecuteEntranceTransition() { 271 // wait till views get their initial position before start transition 272 final View view = getView(); 273 if (view == null) { 274 // fragment view destroyed, transition not needed 275 return; 276 } 277 view.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { 278 @Override 279 public boolean onPreDraw() { 280 view.getViewTreeObserver().removeOnPreDrawListener(this); 281 if (FragmentUtil.getContext(BaseFragment.this) == null || getView() == null) { 282 // bail out if fragment is destroyed immediately after startEntranceTransition 283 return true; 284 } 285 internalCreateEntranceTransition(); 286 onEntranceTransitionStart(); 287 if (mEntranceTransition != null) { 288 runEntranceTransition(mEntranceTransition); 289 } else { 290 mStateMachine.fireEvent(EVT_ENTRANCE_END); 291 } 292 return false; 293 } 294 }); 295 view.invalidate(); 296 } 297 298 void internalCreateEntranceTransition() { 299 mEntranceTransition = createEntranceTransition(); 300 if (mEntranceTransition == null) { 301 return; 302 } 303 TransitionHelper.addTransitionListener(mEntranceTransition, new TransitionListener() { 304 @Override 305 public void onTransitionEnd(Object transition) { 306 mEntranceTransition = null; 307 mStateMachine.fireEvent(EVT_ENTRANCE_END); 308 } 309 }); 310 } 311 312 /** 313 * Returns the {@link ProgressBarManager}. 314 * @return The {@link ProgressBarManager}. 315 */ 316 public final ProgressBarManager getProgressBarManager() { 317 return mProgressBarManager; 318 } 319} 320