ActivityOptions.java revision caa03107d4322b0e30f92e6dc1eb1ea73b1bf747
1/* 2 * Copyright (C) 2012 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.app; 18 19import android.content.Context; 20import android.graphics.Bitmap; 21import android.os.Bundle; 22import android.os.Handler; 23import android.os.IRemoteCallback; 24import android.os.RemoteException; 25import android.os.ResultReceiver; 26import android.transition.Transition; 27import android.util.ArrayMap; 28import android.util.Pair; 29import android.view.View; 30import android.view.Window; 31 32import java.util.List; 33import java.util.Map; 34 35/** 36 * Helper class for building an options Bundle that can be used with 37 * {@link android.content.Context#startActivity(android.content.Intent, android.os.Bundle) 38 * Context.startActivity(Intent, Bundle)} and related methods. 39 */ 40public class ActivityOptions { 41 private static final String TAG = "ActivityOptions"; 42 43 /** 44 * The package name that created the options. 45 * @hide 46 */ 47 public static final String KEY_PACKAGE_NAME = "android:packageName"; 48 49 /** 50 * Type of animation that arguments specify. 51 * @hide 52 */ 53 public static final String KEY_ANIM_TYPE = "android:animType"; 54 55 /** 56 * Custom enter animation resource ID. 57 * @hide 58 */ 59 public static final String KEY_ANIM_ENTER_RES_ID = "android:animEnterRes"; 60 61 /** 62 * Custom exit animation resource ID. 63 * @hide 64 */ 65 public static final String KEY_ANIM_EXIT_RES_ID = "android:animExitRes"; 66 67 /** 68 * Bitmap for thumbnail animation. 69 * @hide 70 */ 71 public static final String KEY_ANIM_THUMBNAIL = "android:animThumbnail"; 72 73 /** 74 * Start X position of thumbnail animation. 75 * @hide 76 */ 77 public static final String KEY_ANIM_START_X = "android:animStartX"; 78 79 /** 80 * Start Y position of thumbnail animation. 81 * @hide 82 */ 83 public static final String KEY_ANIM_START_Y = "android:animStartY"; 84 85 /** 86 * Initial width of the animation. 87 * @hide 88 */ 89 public static final String KEY_ANIM_START_WIDTH = "android:animStartWidth"; 90 91 /** 92 * Initial height of the animation. 93 * @hide 94 */ 95 public static final String KEY_ANIM_START_HEIGHT = "android:animStartHeight"; 96 97 /** 98 * Callback for when animation is started. 99 * @hide 100 */ 101 public static final String KEY_ANIM_START_LISTENER = "android:animStartListener"; 102 103 /** 104 * For Activity transitions, the calling Activity's TransitionListener used to 105 * notify the called Activity when the shared element and the exit transitions 106 * complete. 107 */ 108 private static final String KEY_TRANSITION_COMPLETE_LISTENER 109 = "android:transitionCompleteListener"; 110 111 /** @hide */ 112 public static final int ANIM_NONE = 0; 113 /** @hide */ 114 public static final int ANIM_CUSTOM = 1; 115 /** @hide */ 116 public static final int ANIM_SCALE_UP = 2; 117 /** @hide */ 118 public static final int ANIM_THUMBNAIL_SCALE_UP = 3; 119 /** @hide */ 120 public static final int ANIM_THUMBNAIL_SCALE_DOWN = 4; 121 /** @hide */ 122 public static final int ANIM_SCENE_TRANSITION = 5; 123 124 private String mPackageName; 125 private int mAnimationType = ANIM_NONE; 126 private int mCustomEnterResId; 127 private int mCustomExitResId; 128 private Bitmap mThumbnail; 129 private int mStartX; 130 private int mStartY; 131 private int mStartWidth; 132 private int mStartHeight; 133 private IRemoteCallback mAnimationStartedListener; 134 private ResultReceiver mExitReceiver; 135 136 /** 137 * Create an ActivityOptions specifying a custom animation to run when 138 * the activity is displayed. 139 * 140 * @param context Who is defining this. This is the application that the 141 * animation resources will be loaded from. 142 * @param enterResId A resource ID of the animation resource to use for 143 * the incoming activity. Use 0 for no animation. 144 * @param exitResId A resource ID of the animation resource to use for 145 * the outgoing activity. Use 0 for no animation. 146 * @return Returns a new ActivityOptions object that you can use to 147 * supply these options as the options Bundle when starting an activity. 148 */ 149 public static ActivityOptions makeCustomAnimation(Context context, 150 int enterResId, int exitResId) { 151 return makeCustomAnimation(context, enterResId, exitResId, null, null); 152 } 153 154 /** 155 * Create an ActivityOptions specifying a custom animation to run when 156 * the activity is displayed. 157 * 158 * @param context Who is defining this. This is the application that the 159 * animation resources will be loaded from. 160 * @param enterResId A resource ID of the animation resource to use for 161 * the incoming activity. Use 0 for no animation. 162 * @param exitResId A resource ID of the animation resource to use for 163 * the outgoing activity. Use 0 for no animation. 164 * @param handler If <var>listener</var> is non-null this must be a valid 165 * Handler on which to dispatch the callback; otherwise it should be null. 166 * @param listener Optional OnAnimationStartedListener to find out when the 167 * requested animation has started running. If for some reason the animation 168 * is not executed, the callback will happen immediately. 169 * @return Returns a new ActivityOptions object that you can use to 170 * supply these options as the options Bundle when starting an activity. 171 * @hide 172 */ 173 public static ActivityOptions makeCustomAnimation(Context context, 174 int enterResId, int exitResId, Handler handler, OnAnimationStartedListener listener) { 175 ActivityOptions opts = new ActivityOptions(); 176 opts.mPackageName = context.getPackageName(); 177 opts.mAnimationType = ANIM_CUSTOM; 178 opts.mCustomEnterResId = enterResId; 179 opts.mCustomExitResId = exitResId; 180 opts.setOnAnimationStartedListener(handler, listener); 181 return opts; 182 } 183 184 private void setOnAnimationStartedListener(Handler handler, 185 OnAnimationStartedListener listener) { 186 if (listener != null) { 187 final Handler h = handler; 188 final OnAnimationStartedListener finalListener = listener; 189 mAnimationStartedListener = new IRemoteCallback.Stub() { 190 @Override public void sendResult(Bundle data) throws RemoteException { 191 h.post(new Runnable() { 192 @Override public void run() { 193 finalListener.onAnimationStarted(); 194 } 195 }); 196 } 197 }; 198 } 199 } 200 201 /** 202 * Callback for use with {@link ActivityOptions#makeThumbnailScaleUpAnimation} 203 * to find out when the given animation has started running. 204 * @hide 205 */ 206 public interface OnAnimationStartedListener { 207 void onAnimationStarted(); 208 } 209 210 /** 211 * Create an ActivityOptions specifying an animation where the new 212 * activity is scaled from a small originating area of the screen to 213 * its final full representation. 214 * 215 * <p>If the Intent this is being used with has not set its 216 * {@link android.content.Intent#setSourceBounds Intent.setSourceBounds}, 217 * those bounds will be filled in for you based on the initial 218 * bounds passed in here. 219 * 220 * @param source The View that the new activity is animating from. This 221 * defines the coordinate space for <var>startX</var> and <var>startY</var>. 222 * @param startX The x starting location of the new activity, relative to <var>source</var>. 223 * @param startY The y starting location of the activity, relative to <var>source</var>. 224 * @param startWidth The initial width of the new activity. 225 * @param startHeight The initial height of the new activity. 226 * @return Returns a new ActivityOptions object that you can use to 227 * supply these options as the options Bundle when starting an activity. 228 */ 229 public static ActivityOptions makeScaleUpAnimation(View source, 230 int startX, int startY, int startWidth, int startHeight) { 231 ActivityOptions opts = new ActivityOptions(); 232 opts.mPackageName = source.getContext().getPackageName(); 233 opts.mAnimationType = ANIM_SCALE_UP; 234 int[] pts = new int[2]; 235 source.getLocationOnScreen(pts); 236 opts.mStartX = pts[0] + startX; 237 opts.mStartY = pts[1] + startY; 238 opts.mStartWidth = startWidth; 239 opts.mStartHeight = startHeight; 240 return opts; 241 } 242 243 /** 244 * Create an ActivityOptions specifying an animation where a thumbnail 245 * is scaled from a given position to the new activity window that is 246 * being started. 247 * 248 * <p>If the Intent this is being used with has not set its 249 * {@link android.content.Intent#setSourceBounds Intent.setSourceBounds}, 250 * those bounds will be filled in for you based on the initial 251 * thumbnail location and size provided here. 252 * 253 * @param source The View that this thumbnail is animating from. This 254 * defines the coordinate space for <var>startX</var> and <var>startY</var>. 255 * @param thumbnail The bitmap that will be shown as the initial thumbnail 256 * of the animation. 257 * @param startX The x starting location of the bitmap, relative to <var>source</var>. 258 * @param startY The y starting location of the bitmap, relative to <var>source</var>. 259 * @return Returns a new ActivityOptions object that you can use to 260 * supply these options as the options Bundle when starting an activity. 261 */ 262 public static ActivityOptions makeThumbnailScaleUpAnimation(View source, 263 Bitmap thumbnail, int startX, int startY) { 264 return makeThumbnailScaleUpAnimation(source, thumbnail, startX, startY, null); 265 } 266 267 /** 268 * Create an ActivityOptions specifying an animation where a thumbnail 269 * is scaled from a given position to the new activity window that is 270 * being started. 271 * 272 * @param source The View that this thumbnail is animating from. This 273 * defines the coordinate space for <var>startX</var> and <var>startY</var>. 274 * @param thumbnail The bitmap that will be shown as the initial thumbnail 275 * of the animation. 276 * @param startX The x starting location of the bitmap, relative to <var>source</var>. 277 * @param startY The y starting location of the bitmap, relative to <var>source</var>. 278 * @param listener Optional OnAnimationStartedListener to find out when the 279 * requested animation has started running. If for some reason the animation 280 * is not executed, the callback will happen immediately. 281 * @return Returns a new ActivityOptions object that you can use to 282 * supply these options as the options Bundle when starting an activity. 283 * @hide 284 */ 285 public static ActivityOptions makeThumbnailScaleUpAnimation(View source, 286 Bitmap thumbnail, int startX, int startY, OnAnimationStartedListener listener) { 287 return makeThumbnailAnimation(source, thumbnail, startX, startY, listener, true); 288 } 289 290 /** 291 * Create an ActivityOptions specifying an animation where an activity window 292 * is scaled from a given position to a thumbnail at a specified location. 293 * 294 * @param source The View that this thumbnail is animating to. This 295 * defines the coordinate space for <var>startX</var> and <var>startY</var>. 296 * @param thumbnail The bitmap that will be shown as the final thumbnail 297 * of the animation. 298 * @param startX The x end location of the bitmap, relative to <var>source</var>. 299 * @param startY The y end location of the bitmap, relative to <var>source</var>. 300 * @param listener Optional OnAnimationStartedListener to find out when the 301 * requested animation has started running. If for some reason the animation 302 * is not executed, the callback will happen immediately. 303 * @return Returns a new ActivityOptions object that you can use to 304 * supply these options as the options Bundle when starting an activity. 305 * @hide 306 */ 307 public static ActivityOptions makeThumbnailScaleDownAnimation(View source, 308 Bitmap thumbnail, int startX, int startY, OnAnimationStartedListener listener) { 309 return makeThumbnailAnimation(source, thumbnail, startX, startY, listener, false); 310 } 311 312 private static ActivityOptions makeThumbnailAnimation(View source, 313 Bitmap thumbnail, int startX, int startY, OnAnimationStartedListener listener, 314 boolean scaleUp) { 315 ActivityOptions opts = new ActivityOptions(); 316 opts.mPackageName = source.getContext().getPackageName(); 317 opts.mAnimationType = scaleUp ? ANIM_THUMBNAIL_SCALE_UP : ANIM_THUMBNAIL_SCALE_DOWN; 318 opts.mThumbnail = thumbnail; 319 int[] pts = new int[2]; 320 source.getLocationOnScreen(pts); 321 opts.mStartX = pts[0] + startX; 322 opts.mStartY = pts[1] + startY; 323 opts.setOnAnimationStartedListener(source.getHandler(), listener); 324 return opts; 325 } 326 327 /** 328 * Create an ActivityOptions to transition between Activities using cross-Activity scene 329 * animations. This method carries the position of one shared element to the started Activity. 330 * The position of <code>sharedElement</code> will be used as the epicenter for the 331 * exit Transition. The position of the shared element in the launched Activity will be the 332 * epicenter of its entering Transition. 333 * 334 * <p>This requires {@link android.view.Window#FEATURE_CONTENT_TRANSITIONS} to be 335 * enabled on the calling Activity to cause an exit transition. The same must be in 336 * the called Activity to get an entering transition.</p> 337 * @param window The window containing shared elements. 338 * @param sharedElement The View to transition to the started Activity. sharedElement must 339 * have a non-null sharedElementName. 340 * @param sharedElementName The shared element name as used in the target Activity. This may 341 * be null if it has the same name as sharedElement. 342 * @return Returns a new ActivityOptions object that you can use to 343 * supply these options as the options Bundle when starting an activity. 344 * @see android.transition.Transition#setEpicenterCallback( 345 * android.transition.Transition.EpicenterCallback) 346 */ 347 public static ActivityOptions makeSceneTransitionAnimation(Window window, 348 View sharedElement, String sharedElementName) { 349 return makeSceneTransitionAnimation(window, 350 new SharedElementMappingListener(sharedElement, sharedElementName)); 351 } 352 353 /** 354 * Create an ActivityOptions to transition between Activities using cross-Activity scene 355 * animations. This method carries the position of multiple shared elements to the started 356 * Activity. The position of the first element in the value returned from 357 * {@link android.app.ActivityOptions.ActivityTransitionListener#getSharedElementsMapping()} 358 * will be used as the epicenter for the exit Transition. The position of the associated 359 * shared element in the launched Activity will be the epicenter of its entering Transition. 360 * 361 * <p>This requires {@link android.view.Window#FEATURE_CONTENT_TRANSITIONS} to be 362 * enabled on the calling Activity to cause an exit transition. The same must be in 363 * the called Activity to get an entering transition.</p> 364 * @param window The window containing shared elements. 365 * @param listener The listener to use to monitor activity transition events. 366 * @return Returns a new ActivityOptions object that you can use to 367 * supply these options as the options Bundle when starting an activity. 368 * @see android.transition.Transition#setEpicenterCallback( 369 * android.transition.Transition.EpicenterCallback) 370 */ 371 public static ActivityOptions makeSceneTransitionAnimation(Window window, 372 ActivityTransitionListener listener) { 373 ActivityOptions opts = new ActivityOptions(); 374 opts.mAnimationType = ANIM_SCENE_TRANSITION; 375 ExitTransitionCoordinator exit = new ExitTransitionCoordinator(window, listener); 376 opts.mExitReceiver = exit; 377 return opts; 378 } 379 380 private ActivityOptions() { 381 } 382 383 /** @hide */ 384 public ActivityOptions(Bundle opts) { 385 mPackageName = opts.getString(KEY_PACKAGE_NAME); 386 mAnimationType = opts.getInt(KEY_ANIM_TYPE); 387 switch (mAnimationType) { 388 case ANIM_CUSTOM: 389 mCustomEnterResId = opts.getInt(KEY_ANIM_ENTER_RES_ID, 0); 390 mCustomExitResId = opts.getInt(KEY_ANIM_EXIT_RES_ID, 0); 391 mAnimationStartedListener = IRemoteCallback.Stub.asInterface( 392 opts.getBinder(KEY_ANIM_START_LISTENER)); 393 break; 394 395 case ANIM_SCALE_UP: 396 mStartX = opts.getInt(KEY_ANIM_START_X, 0); 397 mStartY = opts.getInt(KEY_ANIM_START_Y, 0); 398 mStartWidth = opts.getInt(KEY_ANIM_START_WIDTH, 0); 399 mStartHeight = opts.getInt(KEY_ANIM_START_HEIGHT, 0); 400 break; 401 402 case ANIM_THUMBNAIL_SCALE_UP: 403 case ANIM_THUMBNAIL_SCALE_DOWN: 404 mThumbnail = (Bitmap)opts.getParcelable(KEY_ANIM_THUMBNAIL); 405 mStartX = opts.getInt(KEY_ANIM_START_X, 0); 406 mStartY = opts.getInt(KEY_ANIM_START_Y, 0); 407 mAnimationStartedListener = IRemoteCallback.Stub.asInterface( 408 opts.getBinder(KEY_ANIM_START_LISTENER)); 409 break; 410 411 case ANIM_SCENE_TRANSITION: 412 mExitReceiver = opts.getParcelable(KEY_TRANSITION_COMPLETE_LISTENER); 413 break; 414 } 415 } 416 417 /** @hide */ 418 public String getPackageName() { 419 return mPackageName; 420 } 421 422 /** @hide */ 423 public int getAnimationType() { 424 return mAnimationType; 425 } 426 427 /** @hide */ 428 public int getCustomEnterResId() { 429 return mCustomEnterResId; 430 } 431 432 /** @hide */ 433 public int getCustomExitResId() { 434 return mCustomExitResId; 435 } 436 437 /** @hide */ 438 public Bitmap getThumbnail() { 439 return mThumbnail; 440 } 441 442 /** @hide */ 443 public int getStartX() { 444 return mStartX; 445 } 446 447 /** @hide */ 448 public int getStartY() { 449 return mStartY; 450 } 451 452 /** @hide */ 453 public int getStartWidth() { 454 return mStartWidth; 455 } 456 457 /** @hide */ 458 public int getStartHeight() { 459 return mStartHeight; 460 } 461 462 /** @hide */ 463 public IRemoteCallback getOnAnimationStartListener() { 464 return mAnimationStartedListener; 465 } 466 467 /** @hide */ 468 public void dispatchActivityStopped() { 469 if (mExitReceiver != null) { 470 mExitReceiver.send(ActivityTransitionCoordinator.MSG_ACTIVITY_STOPPED, null); 471 } 472 } 473 474 /** @hide */ 475 public void dispatchStartExit() { 476 if (mExitReceiver != null) { 477 mExitReceiver.send(ActivityTransitionCoordinator.MSG_START_EXIT_TRANSITION, null); 478 } 479 } 480 481 /** @hide */ 482 public void abort() { 483 if (mAnimationStartedListener != null) { 484 try { 485 mAnimationStartedListener.sendResult(null); 486 } catch (RemoteException e) { 487 } 488 } 489 } 490 491 /** @hide */ 492 public static void abort(Bundle options) { 493 if (options != null) { 494 (new ActivityOptions(options)).abort(); 495 } 496 } 497 498 /** @hide */ 499 public EnterTransitionCoordinator createEnterActivityTransition(Activity activity) { 500 EnterTransitionCoordinator coordinator = null; 501 if (mAnimationType == ANIM_SCENE_TRANSITION) { 502 coordinator = new EnterTransitionCoordinator(activity, mExitReceiver); 503 } 504 return coordinator; 505 } 506 507 /** 508 * Update the current values in this ActivityOptions from those supplied 509 * in <var>otherOptions</var>. Any values 510 * defined in <var>otherOptions</var> replace those in the base options. 511 */ 512 public void update(ActivityOptions otherOptions) { 513 if (otherOptions.mPackageName != null) { 514 mPackageName = otherOptions.mPackageName; 515 } 516 mExitReceiver = null; 517 switch (otherOptions.mAnimationType) { 518 case ANIM_CUSTOM: 519 mAnimationType = otherOptions.mAnimationType; 520 mCustomEnterResId = otherOptions.mCustomEnterResId; 521 mCustomExitResId = otherOptions.mCustomExitResId; 522 mThumbnail = null; 523 if (mAnimationStartedListener != null) { 524 try { 525 mAnimationStartedListener.sendResult(null); 526 } catch (RemoteException e) { 527 } 528 } 529 mAnimationStartedListener = otherOptions.mAnimationStartedListener; 530 break; 531 case ANIM_SCALE_UP: 532 mAnimationType = otherOptions.mAnimationType; 533 mStartX = otherOptions.mStartX; 534 mStartY = otherOptions.mStartY; 535 mStartWidth = otherOptions.mStartWidth; 536 mStartHeight = otherOptions.mStartHeight; 537 if (mAnimationStartedListener != null) { 538 try { 539 mAnimationStartedListener.sendResult(null); 540 } catch (RemoteException e) { 541 } 542 } 543 mAnimationStartedListener = null; 544 break; 545 case ANIM_THUMBNAIL_SCALE_UP: 546 case ANIM_THUMBNAIL_SCALE_DOWN: 547 mAnimationType = otherOptions.mAnimationType; 548 mThumbnail = otherOptions.mThumbnail; 549 mStartX = otherOptions.mStartX; 550 mStartY = otherOptions.mStartY; 551 if (mAnimationStartedListener != null) { 552 try { 553 mAnimationStartedListener.sendResult(null); 554 } catch (RemoteException e) { 555 } 556 } 557 mAnimationStartedListener = otherOptions.mAnimationStartedListener; 558 break; 559 case ANIM_SCENE_TRANSITION: 560 mAnimationType = otherOptions.mAnimationType; 561 mExitReceiver = otherOptions.mExitReceiver; 562 mThumbnail = null; 563 mAnimationStartedListener = null; 564 break; 565 } 566 } 567 568 /** 569 * Returns the created options as a Bundle, which can be passed to 570 * {@link android.content.Context#startActivity(android.content.Intent, android.os.Bundle) 571 * Context.startActivity(Intent, Bundle)} and related methods. 572 * Note that the returned Bundle is still owned by the ActivityOptions 573 * object; you must not modify it, but can supply it to the startActivity 574 * methods that take an options Bundle. 575 */ 576 public Bundle toBundle() { 577 Bundle b = new Bundle(); 578 if (mPackageName != null) { 579 b.putString(KEY_PACKAGE_NAME, mPackageName); 580 } 581 switch (mAnimationType) { 582 case ANIM_CUSTOM: 583 b.putInt(KEY_ANIM_TYPE, mAnimationType); 584 b.putInt(KEY_ANIM_ENTER_RES_ID, mCustomEnterResId); 585 b.putInt(KEY_ANIM_EXIT_RES_ID, mCustomExitResId); 586 b.putBinder(KEY_ANIM_START_LISTENER, mAnimationStartedListener 587 != null ? mAnimationStartedListener.asBinder() : null); 588 break; 589 case ANIM_SCALE_UP: 590 b.putInt(KEY_ANIM_TYPE, mAnimationType); 591 b.putInt(KEY_ANIM_START_X, mStartX); 592 b.putInt(KEY_ANIM_START_Y, mStartY); 593 b.putInt(KEY_ANIM_START_WIDTH, mStartWidth); 594 b.putInt(KEY_ANIM_START_HEIGHT, mStartHeight); 595 break; 596 case ANIM_THUMBNAIL_SCALE_UP: 597 case ANIM_THUMBNAIL_SCALE_DOWN: 598 b.putInt(KEY_ANIM_TYPE, mAnimationType); 599 b.putParcelable(KEY_ANIM_THUMBNAIL, mThumbnail); 600 b.putInt(KEY_ANIM_START_X, mStartX); 601 b.putInt(KEY_ANIM_START_Y, mStartY); 602 b.putBinder(KEY_ANIM_START_LISTENER, mAnimationStartedListener 603 != null ? mAnimationStartedListener.asBinder() : null); 604 break; 605 case ANIM_SCENE_TRANSITION: 606 b.putInt(KEY_ANIM_TYPE, mAnimationType); 607 if (mExitReceiver != null) { 608 b.putParcelable(KEY_TRANSITION_COMPLETE_LISTENER, mExitReceiver); 609 } 610 break; 611 } 612 return b; 613 } 614 615 /** 616 * Return the filtered options only meant to be seen by the target activity itself 617 * @hide 618 */ 619 public ActivityOptions forTargetActivity() { 620 if (mAnimationType == ANIM_SCENE_TRANSITION) { 621 final ActivityOptions result = new ActivityOptions(); 622 result.update(this); 623 return result; 624 } 625 626 return null; 627 } 628 629 /** 630 * Listener provided in 631 * {@link android.app.ActivityOptions#makeSceneTransitionAnimation(android.view.Window, 632 * android.app.ActivityOptions.ActivityTransitionListener)} or in 633 * {@link android.app.Activity#setActivityTransitionListener( 634 * android.app.ActivityOptions.ActivityTransitionListener)} to monitor the Activity transitions. 635 * The events can be used to customize or override Activity Transition behavior. 636 */ 637 public static class ActivityTransitionListener { 638 /** 639 * Called when the enter Transition is ready to start, but hasn't started yet. If 640 * {@link android.view.Window#getEnterTransition()} is non-null, 641 * The entering views will be {@link View#INVISIBLE}. 642 */ 643 public void onEnterReady() {} 644 645 /** 646 * Called when the remote exiting transition completes. 647 */ 648 public void onRemoteExitComplete() {} 649 650 /** 651 * Called when the start state for shared elements is captured on enter. 652 * 653 * @param sharedElementNames The names of the shared elements that were accepted into 654 * the View hierarchy. 655 * @param sharedElements The shared elements that are part of the View hierarchy. 656 * @param sharedElementSnapshots The Views containing snap shots of the shared element 657 * from the launching Window. These elements will not 658 * be part of the scene, but will be positioned relative 659 * to the Window decor View. 660 */ 661 public void onCaptureSharedElementStart(List<String> sharedElementNames, 662 List<View> sharedElements, List<View> sharedElementSnapshots) {} 663 664 /** 665 * Called when the end state for shared elements is captured on enter. 666 * 667 * @param sharedElementNames The names of the shared elements that were accepted into 668 * the View hierarchy. 669 * @param sharedElements The shared elements that are part of the View hierarchy. 670 * @param sharedElementSnapshots The Views containing snap shots of the shared element 671 * from the launching Window. These elements will not 672 * be part of the scene, but will be positioned relative 673 * to the Window decor View. 674 */ 675 public void onCaptureSharedElementEnd(List<String> sharedElementNames, 676 List<View> sharedElements, List<View> sharedElementSnapshots) {} 677 678 /** 679 * Called when the enter Transition has been started. 680 * @param sharedElementNames The names of shared elements that were transferred. 681 * @param sharedElements The shared elements that were transferred. 682 */ 683 public void onStartEnterTransition(List<String> sharedElementNames, 684 List<View> sharedElements) {} 685 686 /** 687 * Called when the exit Transition has been started. 688 * @param sharedElementNames The names of all shared elements that will be transferred. 689 * @param sharedElements All shared elements that will be transferred. 690 */ 691 public void onStartExitTransition(List<String> sharedElementNames, 692 List<View> sharedElements) {} 693 694 /** 695 * Called when the exiting shared element transition completes. 696 */ 697 public void onSharedElementExitTransitionComplete() {} 698 699 /** 700 * Called on exit when the shared element has been transferred. 701 * @param sharedElementNames The names of all shared elements that were transferred. 702 * @param sharedElements All shared elements that will were transferred. 703 */ 704 public void onSharedElementTransferred(List<String> sharedElementNames, 705 List<View> sharedElements) {} 706 707 /** 708 * Called when the exit transition has completed. 709 */ 710 public void onExitTransitionComplete() {} 711 712 /** 713 * Returns a mapping from a View in the View hierarchy to the shared element name used 714 * in the call. This is called twice -- once when the view is 715 * entering and again when it exits. A null return value indicates that the 716 * View hierachy can be trusted without any remapping. 717 * @return A map from a View in the hierarchy to the shared element name used in the 718 * call. 719 */ 720 public Pair<View, String>[] getSharedElementsMapping() { return null; } 721 722 /** 723 * Returns <code>true</code> if the ActivityTransitionListener will handle removing 724 * rejected shared elements from the scene. If <code>false</code> is returned, a default 725 * animation will be used to remove the rejected shared elements from the scene. 726 * 727 * @param rejectedSharedElements Views containing visual information of shared elements 728 * that are not part of the entering scene. These Views 729 * are positioned relative to the Window decor View. 730 * @return <code>false</code> if the default animation should be used to remove the 731 * rejected shared elements from the scene or <code>true</code> if the listener provides 732 * custom handling. 733 */ 734 public boolean handleRejectedSharedElements(List<View> rejectedSharedElements) { 735 return false; 736 } 737 } 738 739 private static class SharedElementMappingListener extends ActivityTransitionListener { 740 Pair<View, String>[] mSharedElementsMapping = new Pair[1]; 741 742 public SharedElementMappingListener(View view, String name) { 743 mSharedElementsMapping[0] = Pair.create(view, name); 744 } 745 746 @Override 747 public Pair<View, String>[] getSharedElementsMapping() { 748 return mSharedElementsMapping; 749 } 750 } 751} 752