1/* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package android.support.transition; 18 19import android.animation.Animator; 20import android.animation.TimeInterpolator; 21import android.os.Build; 22import android.support.annotation.IdRes; 23import android.support.annotation.NonNull; 24import android.support.annotation.Nullable; 25import android.view.SurfaceView; 26import android.view.TextureView; 27import android.view.View; 28import android.view.ViewGroup; 29import android.widget.Spinner; 30 31import java.util.List; 32 33/** 34 * A Transition holds information about animations that will be run on its 35 * targets during a scene change. Subclasses of this abstract class may 36 * choreograph several child transitions ({@link TransitionSet} or they may 37 * perform custom animations themselves. Any Transition has two main jobs: 38 * (1) capture property values, and (2) play animations based on changes to 39 * captured property values. A custom transition knows what property values 40 * on View objects are of interest to it, and also knows how to animate 41 * changes to those values. For example, the {@link Fade} transition tracks 42 * changes to visibility-related properties and is able to construct and run 43 * animations that fade items in or out based on changes to those properties. 44 * 45 * <p>Note: Transitions may not work correctly with either {@link SurfaceView} 46 * or {@link TextureView}, due to the way that these views are displayed 47 * on the screen. For SurfaceView, the problem is that the view is updated from 48 * a non-UI thread, so changes to the view due to transitions (such as moving 49 * and resizing the view) may be out of sync with the display inside those bounds. 50 * TextureView is more compatible with transitions in general, but some 51 * specific transitions (such as {@link Fade}) may not be compatible 52 * with TextureView because they rely on {@link android.view.ViewOverlay} 53 * functionality, which does not currently work with TextureView.</p> 54 * 55 * <p>Unlike the platform version, this does not support declaration by XML resources.</p> 56 */ 57public abstract class Transition implements TransitionInterface { 58 59 /* package */ TransitionImpl mImpl; 60 61 /** 62 * Constructs a Transition object with no target objects. A transition with 63 * no targets defaults to running on all target objects in the scene hierarchy 64 * (if the transition is not contained in a TransitionSet), or all target 65 * objects passed down from its parent (if it is in a TransitionSet). 66 */ 67 public Transition() { 68 this(false); 69 } 70 71 // Hidden constructor for built-in transitions 72 Transition(boolean deferred) { 73 if (!deferred) { 74 if (Build.VERSION.SDK_INT >= 23) { 75 mImpl = new TransitionApi23(); 76 } else if (Build.VERSION.SDK_INT >= 19) { 77 mImpl = new TransitionKitKat(); 78 } else { 79 mImpl = new TransitionIcs(); 80 } 81 mImpl.init(this); 82 } 83 } 84 85 /** 86 * Adds a listener to the set of listeners that are sent events through the 87 * life of an animation, such as start, repeat, and end. 88 * 89 * @param listener the listener to be added to the current set of listeners 90 * for this animation. 91 * @return This transition object. 92 */ 93 @NonNull 94 public Transition addListener(@NonNull TransitionListener listener) { 95 mImpl.addListener(listener); 96 return this; 97 } 98 99 /** 100 * Sets the target view instances that this Transition is interested in 101 * animating. By default, there are no targets, and a Transition will 102 * listen for changes on every view in the hierarchy below the sceneRoot 103 * of the Scene being transitioned into. Setting targets constrains 104 * the Transition to only listen for, and act on, these views. 105 * All other views will be ignored. 106 * 107 * <p>The target list is like the {@link #addTarget(int) targetId} 108 * list except this list specifies the actual View instances, not the ids 109 * of the views. This is an important distinction when scene changes involve 110 * view hierarchies which have been inflated separately; different views may 111 * share the same id but not actually be the same instance. If the transition 112 * should treat those views as the same, then {@link #addTarget(int)} should be used 113 * instead of {@link #addTarget(View)}. If, on the other hand, scene changes involve 114 * changes all within the same view hierarchy, among views which do not 115 * necessarily have ids set on them, then the target list of views may be more 116 * convenient.</p> 117 * 118 * @param target A View on which the Transition will act, must be non-null. 119 * @return The Transition to which the target is added. 120 * Returning the same object makes it easier to chain calls during 121 * construction, such as 122 * <code>transitionSet.addTransitions(new Fade()).addTarget(someView);</code> 123 * @see #addTarget(int) 124 */ 125 @NonNull 126 public Transition addTarget(@NonNull View target) { 127 mImpl.addTarget(target); 128 return this; 129 } 130 131 /** 132 * Adds the id of a target view that this Transition is interested in 133 * animating. By default, there are no targetIds, and a Transition will 134 * listen for changes on every view in the hierarchy below the sceneRoot 135 * of the Scene being transitioned into. Setting targetIds constrains 136 * the Transition to only listen for, and act on, views with these IDs. 137 * Views with different IDs, or no IDs whatsoever, will be ignored. 138 * 139 * <p>Note that using ids to specify targets implies that ids should be unique 140 * within the view hierarchy underneath the scene root.</p> 141 * 142 * @param targetId The id of a target view, must be a positive number. 143 * @return The Transition to which the targetId is added. 144 * Returning the same object makes it easier to chain calls during 145 * construction, such as 146 * <code>transitionSet.addTransitions(new Fade()).addTarget(someId);</code> 147 * @see View#getId() 148 */ 149 @NonNull 150 public Transition addTarget(@IdRes int targetId) { 151 mImpl.addTarget(targetId); 152 return this; 153 } 154 155 /** 156 * Captures the values in the end scene for the properties that this 157 * transition monitors. These values are then passed as the endValues 158 * structure in a later call to 159 * {@link #createAnimator(ViewGroup, TransitionValues, TransitionValues)}. 160 * The main concern for an implementation is what the 161 * properties are that the transition cares about and what the values are 162 * for all of those properties. The start and end values will be compared 163 * later during the 164 * {@link #createAnimator(ViewGroup, TransitionValues, TransitionValues)} 165 * method to determine what, if any, animations, should be run. 166 * 167 * <p>Subclasses must implement this method. The method should only be called by the 168 * transition system; it is not intended to be called from external classes.</p> 169 * 170 * @param transitionValues The holder for any values that the Transition 171 * wishes to store. Values are stored in the <code>values</code> field 172 * of this TransitionValues object and are keyed from 173 * a String value. For example, to store a view's rotation value, 174 * a transition might call 175 * <code>transitionValues.values.put("appname:transitionname:rotation", 176 * view.getRotation())</code>. The target view will already be stored 177 * in 178 * the transitionValues structure when this method is called. 179 * @see #captureStartValues(TransitionValues) 180 * @see #createAnimator(ViewGroup, TransitionValues, TransitionValues) 181 */ 182 @Override 183 public abstract void captureEndValues(@NonNull TransitionValues transitionValues); 184 185 /** 186 * Captures the values in the start scene for the properties that this 187 * transition monitors. These values are then passed as the startValues 188 * structure in a later call to 189 * {@link #createAnimator(ViewGroup, TransitionValues, TransitionValues)}. 190 * The main concern for an implementation is what the 191 * properties are that the transition cares about and what the values are 192 * for all of those properties. The start and end values will be compared 193 * later during the 194 * {@link #createAnimator(ViewGroup, TransitionValues, TransitionValues)} 195 * method to determine what, if any, animations, should be run. 196 * 197 * <p>Subclasses must implement this method. The method should only be called by the 198 * transition system; it is not intended to be called from external classes.</p> 199 * 200 * @param transitionValues The holder for any values that the Transition 201 * wishes to store. Values are stored in the <code>values</code> field 202 * of this TransitionValues object and are keyed from 203 * a String value. For example, to store a view's rotation value, 204 * a transition might call 205 * <code>transitionValues.values.put("appname:transitionname:rotation", 206 * view.getRotation())</code>. The target view will already be stored 207 * in 208 * the transitionValues structure when this method is called. 209 * @see #captureEndValues(TransitionValues) 210 * @see #createAnimator(ViewGroup, TransitionValues, TransitionValues) 211 */ 212 @Override 213 public abstract void captureStartValues(@NonNull TransitionValues transitionValues); 214 215 /** 216 * This method creates an animation that will be run for this transition 217 * given the information in the startValues and endValues structures captured 218 * earlier for the start and end scenes. Subclasses of Transition should override 219 * this method. The method should only be called by the transition system; it is 220 * not intended to be called from external classes. 221 * 222 * <p>This method is called by the transition's parent (all the way up to the 223 * topmost Transition in the hierarchy) with the sceneRoot and start/end 224 * values that the transition may need to set up initial target values 225 * and construct an appropriate animation. For example, if an overall 226 * Transition is a {@link TransitionSet} consisting of several 227 * child transitions in sequence, then some of the child transitions may 228 * want to set initial values on target views prior to the overall 229 * Transition commencing, to put them in an appropriate state for the 230 * delay between that start and the child Transition start time. For 231 * example, a transition that fades an item in may wish to set the starting 232 * alpha value to 0, to avoid it blinking in prior to the transition 233 * actually starting the animation. This is necessary because the scene 234 * change that triggers the Transition will automatically set the end-scene 235 * on all target views, so a Transition that wants to animate from a 236 * different value should set that value prior to returning from this method.</p> 237 * 238 * <p>Additionally, a Transition can perform logic to determine whether 239 * the transition needs to run on the given target and start/end values. 240 * For example, a transition that resizes objects on the screen may wish 241 * to avoid running for views which are not present in either the start 242 * or end scenes.</p> 243 * 244 * <p>If there is an animator created and returned from this method, the 245 * transition mechanism will apply any applicable duration, startDelay, 246 * and interpolator to that animation and start it. A return value of 247 * <code>null</code> indicates that no animation should run. The default 248 * implementation returns null.</p> 249 * 250 * <p>The method is called for every applicable target object, which is 251 * stored in the {@link TransitionValues#view} field.</p> 252 * 253 * @param sceneRoot The root of the transition hierarchy. 254 * @param startValues The values for a specific target in the start scene. 255 * @param endValues The values for the target in the end scene. 256 * @return A Animator to be started at the appropriate time in the 257 * overall transition for this scene change. A null value means no animation 258 * should be run. 259 */ 260 @Override 261 @Nullable 262 public Animator createAnimator(@NonNull ViewGroup sceneRoot, 263 @Nullable TransitionValues startValues, @Nullable TransitionValues endValues) { 264 return null; 265 } 266 267 /** 268 * Whether to add the children of given target to the list of target children 269 * to exclude from this transition. The <code>exclude</code> parameter specifies 270 * whether the target should be added to or removed from the excluded list. 271 * 272 * <p>Excluding targets is a general mechanism for allowing transitions to run on 273 * a view hierarchy while skipping target views that should not be part of 274 * the transition. For example, you may want to avoid animating children 275 * of a specific ListView or Spinner. Views can be excluded either by their 276 * id, or by their instance reference, or by the Class of that view 277 * (eg, {@link Spinner}).</p> 278 * 279 * @param target The target to ignore when running this transition. 280 * @param exclude Whether to add the target to or remove the target from the 281 * current list of excluded targets. 282 * @return This transition object. 283 * @see #excludeTarget(View, boolean) 284 * @see #excludeChildren(int, boolean) 285 * @see #excludeChildren(Class, boolean) 286 */ 287 @NonNull 288 public Transition excludeChildren(@NonNull View target, boolean exclude) { 289 mImpl.excludeChildren(target, exclude); 290 return this; 291 } 292 293 /** 294 * Whether to add the children of the given id to the list of targets to exclude 295 * from this transition. The <code>exclude</code> parameter specifies whether 296 * the children of the target should be added to or removed from the excluded list. 297 * Excluding children in this way provides a simple mechanism for excluding all 298 * children of specific targets, rather than individually excluding each 299 * child individually. 300 * 301 * <p>Excluding targets is a general mechanism for allowing transitions to run on 302 * a view hierarchy while skipping target views that should not be part of 303 * the transition. For example, you may want to avoid animating children 304 * of a specific ListView or Spinner. Views can be excluded either by their 305 * id, or by their instance reference, or by the Class of that view 306 * (eg, {@link Spinner}).</p> 307 * 308 * @param targetId The id of a target whose children should be ignored when running 309 * this transition. 310 * @param exclude Whether to add the target to or remove the target from the 311 * current list of excluded-child targets. 312 * @return This transition object. 313 * @see #excludeTarget(int, boolean) 314 * @see #excludeChildren(View, boolean) 315 * @see #excludeChildren(Class, boolean) 316 */ 317 @NonNull 318 public Transition excludeChildren(@IdRes int targetId, boolean exclude) { 319 mImpl.excludeChildren(targetId, exclude); 320 return this; 321 } 322 323 /** 324 * Whether to add the given type to the list of types whose children should 325 * be excluded from this transition. The <code>exclude</code> parameter 326 * specifies whether the target type should be added to or removed from 327 * the excluded list. 328 * 329 * <p>Excluding targets is a general mechanism for allowing transitions to run on 330 * a view hierarchy while skipping target views that should not be part of 331 * the transition. For example, you may want to avoid animating children 332 * of a specific ListView or Spinner. Views can be excluded either by their 333 * id, or by their instance reference, or by the Class of that view 334 * (eg, {@link Spinner}).</p> 335 * 336 * @param type The type to ignore when running this transition. 337 * @param exclude Whether to add the target type to or remove it from the 338 * current list of excluded target types. 339 * @return This transition object. 340 * @see #excludeTarget(Class, boolean) 341 * @see #excludeChildren(int, boolean) 342 * @see #excludeChildren(View, boolean) 343 */ 344 @NonNull 345 public Transition excludeChildren(@NonNull Class type, boolean exclude) { 346 mImpl.excludeChildren(type, exclude); 347 return this; 348 } 349 350 /** 351 * Whether to add the given target to the list of targets to exclude from this 352 * transition. The <code>exclude</code> parameter specifies whether the target 353 * should be added to or removed from the excluded list. 354 * 355 * <p>Excluding targets is a general mechanism for allowing transitions to run on 356 * a view hierarchy while skipping target views that should not be part of 357 * the transition. For example, you may want to avoid animating children 358 * of a specific ListView or Spinner. Views can be excluded either by their 359 * id, or by their instance reference, or by the Class of that view 360 * (eg, {@link Spinner}).</p> 361 * 362 * @param target The target to ignore when running this transition. 363 * @param exclude Whether to add the target to or remove the target from the 364 * current list of excluded targets. 365 * @return This transition object. 366 * @see #excludeChildren(View, boolean) 367 * @see #excludeTarget(int, boolean) 368 * @see #excludeTarget(Class, boolean) 369 */ 370 @NonNull 371 public Transition excludeTarget(@NonNull View target, boolean exclude) { 372 mImpl.excludeTarget(target, exclude); 373 return this; 374 } 375 376 /** 377 * Whether to add the given id to the list of target ids to exclude from this 378 * transition. The <code>exclude</code> parameter specifies whether the target 379 * should be added to or removed from the excluded list. 380 * 381 * <p>Excluding targets is a general mechanism for allowing transitions to run on 382 * a view hierarchy while skipping target views that should not be part of 383 * the transition. For example, you may want to avoid animating children 384 * of a specific ListView or Spinner. Views can be excluded either by their 385 * id, or by their instance reference, or by the Class of that view 386 * (eg, {@link Spinner}).</p> 387 * 388 * @param targetId The id of a target to ignore when running this transition. 389 * @param exclude Whether to add the target to or remove the target from the 390 * current list of excluded targets. 391 * @return This transition object. 392 * @see #excludeChildren(int, boolean) 393 * @see #excludeTarget(View, boolean) 394 * @see #excludeTarget(Class, boolean) 395 */ 396 @NonNull 397 public Transition excludeTarget(@IdRes int targetId, boolean exclude) { 398 mImpl.excludeTarget(targetId, exclude); 399 return this; 400 } 401 402 /** 403 * Whether to add the given type to the list of types to exclude from this 404 * transition. The <code>exclude</code> parameter specifies whether the target 405 * type should be added to or removed from the excluded list. 406 * 407 * <p>Excluding targets is a general mechanism for allowing transitions to run on 408 * a view hierarchy while skipping target views that should not be part of 409 * the transition. For example, you may want to avoid animating children 410 * of a specific ListView or Spinner. Views can be excluded either by their 411 * id, or by their instance reference, or by the Class of that view 412 * (eg, {@link Spinner}).</p> 413 * 414 * @param type The type to ignore when running this transition. 415 * @param exclude Whether to add the target type to or remove it from the 416 * current list of excluded target types. 417 * @return This transition object. 418 * @see #excludeChildren(Class, boolean) 419 * @see #excludeTarget(int, boolean) 420 * @see #excludeTarget(View, boolean) 421 */ 422 @NonNull 423 public Transition excludeTarget(@NonNull Class type, boolean exclude) { 424 mImpl.excludeTarget(type, exclude); 425 return this; 426 } 427 428 /** 429 * Returns the duration set on this transition. If no duration has been set, 430 * the returned value will be negative, indicating that resulting animators will 431 * retain their own durations. 432 * 433 * @return The duration set on this transition, in milliseconds, if one has been 434 * set, otherwise returns a negative number. 435 */ 436 public long getDuration() { 437 return mImpl.getDuration(); 438 } 439 440 /** 441 * Sets the duration of this transition. By default, there is no duration 442 * (indicated by a negative number), which means that the Animator created by 443 * the transition will have its own specified duration. If the duration of a 444 * Transition is set, that duration will override the Animator duration. 445 * 446 * @param duration The length of the animation, in milliseconds. 447 * @return This transition object. 448 * @attr name android:duration 449 */ 450 @NonNull 451 public Transition setDuration(long duration) { 452 mImpl.setDuration(duration); 453 return this; 454 } 455 456 /** 457 * Returns the interpolator set on this transition. If no interpolator has been set, 458 * the returned value will be null, indicating that resulting animators will 459 * retain their own interpolators. 460 * 461 * @return The interpolator set on this transition, if one has been set, otherwise 462 * returns null. 463 */ 464 @Nullable 465 public TimeInterpolator getInterpolator() { 466 return mImpl.getInterpolator(); 467 } 468 469 /** 470 * Sets the interpolator of this transition. By default, the interpolator 471 * is null, which means that the Animator created by the transition 472 * will have its own specified interpolator. If the interpolator of a 473 * Transition is set, that interpolator will override the Animator interpolator. 474 * 475 * @param interpolator The time interpolator used by the transition 476 * @return This transition object. 477 * @attr name android:interpolator 478 */ 479 @NonNull 480 public Transition setInterpolator(@Nullable TimeInterpolator interpolator) { 481 mImpl.setInterpolator(interpolator); 482 return this; 483 } 484 485 /** 486 * Returns the name of this Transition. This name is used internally to distinguish 487 * between different transitions to determine when interrupting transitions overlap. 488 * For example, a ChangeBounds running on the same target view as another ChangeBounds 489 * should determine whether the old transition is animating to different end values 490 * and should be canceled in favor of the new transition. 491 * 492 * <p>By default, a Transition's name is simply the value of {@link Class#getName()}, 493 * but subclasses are free to override and return something different.</p> 494 * 495 * @return The name of this transition. 496 */ 497 @NonNull 498 public String getName() { 499 return mImpl.getName(); 500 } 501 502 /** 503 * Returns the startDelay set on this transition. If no startDelay has been set, 504 * the returned value will be negative, indicating that resulting animators will 505 * retain their own startDelays. 506 * 507 * @return The startDelay set on this transition, in milliseconds, if one has 508 * been set, otherwise returns a negative number. 509 */ 510 public long getStartDelay() { 511 return mImpl.getStartDelay(); 512 } 513 514 /** 515 * Sets the startDelay of this transition. By default, there is no delay 516 * (indicated by a negative number), which means that the Animator created by 517 * the transition will have its own specified startDelay. If the delay of a 518 * Transition is set, that delay will override the Animator delay. 519 * 520 * @param startDelay The length of the delay, in milliseconds. 521 * @return This transition object. 522 * @attr name android:startDelay 523 */ 524 @NonNull 525 public Transition setStartDelay(long startDelay) { 526 mImpl.setStartDelay(startDelay); 527 return this; 528 } 529 530 /** 531 * Returns the array of target IDs that this transition limits itself to 532 * tracking and animating. If the array is null for both this method and 533 * {@link #getTargets()}, then this transition is 534 * not limited to specific views, and will handle changes to any views 535 * in the hierarchy of a scene change. 536 * 537 * @return the list of target IDs 538 */ 539 @NonNull 540 public List<Integer> getTargetIds() { 541 return mImpl.getTargetIds(); 542 } 543 544 /** 545 * Returns the array of target views that this transition limits itself to 546 * tracking and animating. If the array is null for both this method and 547 * {@link #getTargetIds()}, then this transition is 548 * not limited to specific views, and will handle changes to any views 549 * in the hierarchy of a scene change. 550 * 551 * @return the list of target views 552 */ 553 @NonNull 554 public List<View> getTargets() { 555 return mImpl.getTargets(); 556 } 557 558 /** 559 * Returns the set of property names used stored in the {@link TransitionValues} 560 * object passed into {@link #captureStartValues(TransitionValues)} that 561 * this transition cares about for the purposes of canceling overlapping animations. 562 * When any transition is started on a given scene root, all transitions 563 * currently running on that same scene root are checked to see whether the 564 * properties on which they based their animations agree with the end values of 565 * the same properties in the new transition. If the end values are not equal, 566 * then the old animation is canceled since the new transition will start a new 567 * animation to these new values. If the values are equal, the old animation is 568 * allowed to continue and no new animation is started for that transition. 569 * 570 * <p>A transition does not need to override this method. However, not doing so 571 * will mean that the cancellation logic outlined in the previous paragraph 572 * will be skipped for that transition, possibly leading to artifacts as 573 * old transitions and new transitions on the same targets run in parallel, 574 * animating views toward potentially different end values.</p> 575 * 576 * @return An array of property names as described in the class documentation for 577 * {@link TransitionValues}. The default implementation returns <code>null</code>. 578 */ 579 @Nullable 580 public String[] getTransitionProperties() { 581 return mImpl.getTransitionProperties(); 582 } 583 584 /** 585 * This method can be called by transitions to get the TransitionValues for 586 * any particular view during the transition-playing process. This might be 587 * necessary, for example, to query the before/after state of related views 588 * for a given transition. 589 */ 590 @NonNull 591 public TransitionValues getTransitionValues(@NonNull View view, boolean start) { 592 return mImpl.getTransitionValues(view, start); 593 } 594 595 /** 596 * Removes a listener from the set listening to this animation. 597 * 598 * @param listener the listener to be removed from the current set of 599 * listeners for this transition. 600 * @return This transition object. 601 */ 602 @NonNull 603 public Transition removeListener(@NonNull TransitionListener listener) { 604 mImpl.removeListener(listener); 605 return this; 606 } 607 608 /** 609 * Removes the given target from the list of targets that this Transition 610 * is interested in animating. 611 * 612 * @param target The target view, must be non-null. 613 * @return Transition The Transition from which the target is removed. 614 * Returning the same object makes it easier to chain calls during 615 * construction, such as 616 * <code>transitionSet.addTransitions(new Fade()).removeTarget(someView);</code> 617 */ 618 @NonNull 619 public Transition removeTarget(@NonNull View target) { 620 mImpl.removeTarget(target); 621 return this; 622 } 623 624 /** 625 * Removes the given targetId from the list of ids that this Transition 626 * is interested in animating. 627 * 628 * @param targetId The id of a target view, must be a positive number. 629 * @return The Transition from which the targetId is removed. 630 * Returning the same object makes it easier to chain calls during 631 * construction, such as 632 * <code>transitionSet.addTransitions(new Fade()).removeTargetId(someId);</code> 633 */ 634 @NonNull 635 public Transition removeTarget(@IdRes int targetId) { 636 mImpl.removeTarget(targetId); 637 return this; 638 } 639 640 @Override 641 public String toString() { 642 return mImpl.toString(); 643 } 644 645 /** 646 * A transition listener receives notifications from a transition. 647 * Notifications indicate transition lifecycle events. 648 */ 649 public interface TransitionListener extends TransitionInterfaceListener<Transition> { 650 651 /** 652 * Notification about the start of the transition. 653 * 654 * @param transition The started transition. 655 */ 656 @Override 657 void onTransitionStart(@NonNull Transition transition); 658 659 /** 660 * Notification about the end of the transition. Canceled transitions 661 * will always notify listeners of both the cancellation and end 662 * events. That is, {@link #onTransitionEnd(Transition)} is always called, 663 * regardless of whether the transition was canceled or played 664 * through to completion. 665 * 666 * @param transition The transition which reached its end. 667 */ 668 @Override 669 void onTransitionEnd(@NonNull Transition transition); 670 671 /** 672 * Notification about the cancellation of the transition. 673 * Note that cancel may be called by a parent {@link TransitionSet} on 674 * a child transition which has not yet started. This allows the child 675 * transition to restore state on target objects which was set at 676 * {@link #createAnimator(android.view.ViewGroup, TransitionValues, TransitionValues) 677 * createAnimator()} time. 678 * 679 * @param transition The transition which was canceled. 680 */ 681 @Override 682 void onTransitionCancel(@NonNull Transition transition); 683 684 /** 685 * Notification when a transition is paused. 686 * Note that createAnimator() may be called by a parent {@link TransitionSet} on 687 * a child transition which has not yet started. This allows the child 688 * transition to restore state on target objects which was set at 689 * {@link #createAnimator(android.view.ViewGroup, TransitionValues, TransitionValues) 690 * createAnimator()} time. 691 * 692 * @param transition The transition which was paused. 693 */ 694 @Override 695 void onTransitionPause(@NonNull Transition transition); 696 697 /** 698 * Notification when a transition is resumed. 699 * Note that resume() may be called by a parent {@link TransitionSet} on 700 * a child transition which has not yet started. This allows the child 701 * transition to restore state which may have changed in an earlier call 702 * to {@link #onTransitionPause(Transition)}. 703 * 704 * @param transition The transition which was resumed. 705 */ 706 @Override 707 void onTransitionResume(@NonNull Transition transition); 708 } 709 710} 711