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 17 package android.app; 18 19 import android.content.Context; 20 import android.content.Intent; 21 import android.graphics.Bitmap; 22 import android.os.Bundle; 23 import android.os.Handler; 24 import android.os.IRemoteCallback; 25 import android.os.RemoteException; 26 import android.os.ResultReceiver; 27 import android.util.Pair; 28 import android.view.View; 29 import android.view.Window; 30 31 import java.util.ArrayList; 32 33 /** 34 * Helper class for building an options Bundle that can be used with 35 * {@link android.content.Context#startActivity(android.content.Intent, android.os.Bundle) 36 * Context.startActivity(Intent, Bundle)} and related methods. 37 */ 38 public class ActivityOptions { 39 private static final String TAG = "ActivityOptions"; 40 41 /** 42 * The package name that created the options. 43 * @hide 44 */ 45 public static final String KEY_PACKAGE_NAME = "android:packageName"; 46 47 /** 48 * Type of animation that arguments specify. 49 * @hide 50 */ 51 public static final String KEY_ANIM_TYPE = "android:animType"; 52 53 /** 54 * Custom enter animation resource ID. 55 * @hide 56 */ 57 public static final String KEY_ANIM_ENTER_RES_ID = "android:animEnterRes"; 58 59 /** 60 * Custom exit animation resource ID. 61 * @hide 62 */ 63 public static final String KEY_ANIM_EXIT_RES_ID = "android:animExitRes"; 64 65 /** 66 * Custom in-place animation resource ID. 67 * @hide 68 */ 69 public static final String KEY_ANIM_IN_PLACE_RES_ID = "android:animInPlaceRes"; 70 71 /** 72 * Bitmap for thumbnail animation. 73 * @hide 74 */ 75 public static final String KEY_ANIM_THUMBNAIL = "android:animThumbnail"; 76 77 /** 78 * Start X position of thumbnail animation. 79 * @hide 80 */ 81 public static final String KEY_ANIM_START_X = "android:animStartX"; 82 83 /** 84 * Start Y position of thumbnail animation. 85 * @hide 86 */ 87 public static final String KEY_ANIM_START_Y = "android:animStartY"; 88 89 /** 90 * Initial width of the animation. 91 * @hide 92 */ 93 public static final String KEY_ANIM_WIDTH = "android:animWidth"; 94 95 /** 96 * Initial height of the animation. 97 * @hide 98 */ 99 public static final String KEY_ANIM_HEIGHT = "android:animHeight"; 100 101 /** 102 * Callback for when animation is started. 103 * @hide 104 */ 105 public static final String KEY_ANIM_START_LISTENER = "android:animStartListener"; 106 107 /** 108 * For Activity transitions, the calling Activity's TransitionListener used to 109 * notify the called Activity when the shared element and the exit transitions 110 * complete. 111 */ 112 private static final String KEY_TRANSITION_COMPLETE_LISTENER 113 = "android:transitionCompleteListener"; 114 115 private static final String KEY_TRANSITION_IS_RETURNING = "android:transitionIsReturning"; 116 private static final String KEY_TRANSITION_SHARED_ELEMENTS = "android:sharedElementNames"; 117 private static final String KEY_RESULT_DATA = "android:resultData"; 118 private static final String KEY_RESULT_CODE = "android:resultCode"; 119 private static final String KEY_EXIT_COORDINATOR_INDEX = "android:exitCoordinatorIndex"; 120 121 /** @hide */ 122 public static final int ANIM_NONE = 0; 123 /** @hide */ 124 public static final int ANIM_CUSTOM = 1; 125 /** @hide */ 126 public static final int ANIM_SCALE_UP = 2; 127 /** @hide */ 128 public static final int ANIM_THUMBNAIL_SCALE_UP = 3; 129 /** @hide */ 130 public static final int ANIM_THUMBNAIL_SCALE_DOWN = 4; 131 /** @hide */ 132 public static final int ANIM_SCENE_TRANSITION = 5; 133 /** @hide */ 134 public static final int ANIM_DEFAULT = 6; 135 /** @hide */ 136 public static final int ANIM_LAUNCH_TASK_BEHIND = 7; 137 /** @hide */ 138 public static final int ANIM_THUMBNAIL_ASPECT_SCALE_UP = 8; 139 /** @hide */ 140 public static final int ANIM_THUMBNAIL_ASPECT_SCALE_DOWN = 9; 141 /** @hide */ 142 public static final int ANIM_CUSTOM_IN_PLACE = 10; 143 144 private String mPackageName; 145 private int mAnimationType = ANIM_NONE; 146 private int mCustomEnterResId; 147 private int mCustomExitResId; 148 private int mCustomInPlaceResId; 149 private Bitmap mThumbnail; 150 private int mStartX; 151 private int mStartY; 152 private int mWidth; 153 private int mHeight; 154 private IRemoteCallback mAnimationStartedListener; 155 private ResultReceiver mTransitionReceiver; 156 private boolean mIsReturning; 157 private ArrayList<String> mSharedElementNames; 158 private Intent mResultData; 159 private int mResultCode; 160 private int mExitCoordinatorIndex; 161 162 /** 163 * Create an ActivityOptions specifying a custom animation to run when 164 * the activity is displayed. 165 * 166 * @param context Who is defining this. This is the application that the 167 * animation resources will be loaded from. 168 * @param enterResId A resource ID of the animation resource to use for 169 * the incoming activity. Use 0 for no animation. 170 * @param exitResId A resource ID of the animation resource to use for 171 * the outgoing activity. Use 0 for no animation. 172 * @return Returns a new ActivityOptions object that you can use to 173 * supply these options as the options Bundle when starting an activity. 174 */ 175 public static ActivityOptions makeCustomAnimation(Context context, 176 int enterResId, int exitResId) { 177 return makeCustomAnimation(context, enterResId, exitResId, null, null); 178 } 179 180 /** 181 * Create an ActivityOptions specifying a custom animation to run when 182 * the activity is displayed. 183 * 184 * @param context Who is defining this. This is the application that the 185 * animation resources will be loaded from. 186 * @param enterResId A resource ID of the animation resource to use for 187 * the incoming activity. Use 0 for no animation. 188 * @param exitResId A resource ID of the animation resource to use for 189 * the outgoing activity. Use 0 for no animation. 190 * @param handler If <var>listener</var> is non-null this must be a valid 191 * Handler on which to dispatch the callback; otherwise it should be null. 192 * @param listener Optional OnAnimationStartedListener to find out when the 193 * requested animation has started running. If for some reason the animation 194 * is not executed, the callback will happen immediately. 195 * @return Returns a new ActivityOptions object that you can use to 196 * supply these options as the options Bundle when starting an activity. 197 * @hide 198 */ 199 public static ActivityOptions makeCustomAnimation(Context context, 200 int enterResId, int exitResId, Handler handler, OnAnimationStartedListener listener) { 201 ActivityOptions opts = new ActivityOptions(); 202 opts.mPackageName = context.getPackageName(); 203 opts.mAnimationType = ANIM_CUSTOM; 204 opts.mCustomEnterResId = enterResId; 205 opts.mCustomExitResId = exitResId; 206 opts.setOnAnimationStartedListener(handler, listener); 207 return opts; 208 } 209 210 /** 211 * Creates an ActivityOptions specifying a custom animation to run in place on an existing 212 * activity. 213 * 214 * @param context Who is defining this. This is the application that the 215 * animation resources will be loaded from. 216 * @param animId A resource ID of the animation resource to use for 217 * the incoming activity. 218 * @return Returns a new ActivityOptions object that you can use to 219 * supply these options as the options Bundle when running an in-place animation. 220 * @hide 221 */ 222 public static ActivityOptions makeCustomInPlaceAnimation(Context context, int animId) { 223 if (animId == 0) { 224 throw new RuntimeException("You must specify a valid animation."); 225 } 226 227 ActivityOptions opts = new ActivityOptions(); 228 opts.mPackageName = context.getPackageName(); 229 opts.mAnimationType = ANIM_CUSTOM_IN_PLACE; 230 opts.mCustomInPlaceResId = animId; 231 return opts; 232 } 233 234 private void setOnAnimationStartedListener(Handler handler, 235 OnAnimationStartedListener listener) { 236 if (listener != null) { 237 final Handler h = handler; 238 final OnAnimationStartedListener finalListener = listener; 239 mAnimationStartedListener = new IRemoteCallback.Stub() { 240 @Override public void sendResult(Bundle data) throws RemoteException { 241 h.post(new Runnable() { 242 @Override public void run() { 243 finalListener.onAnimationStarted(); 244 } 245 }); 246 } 247 }; 248 } 249 } 250 251 /** 252 * Callback for use with {@link ActivityOptions#makeThumbnailScaleUpAnimation} 253 * to find out when the given animation has started running. 254 * @hide 255 */ 256 public interface OnAnimationStartedListener { 257 void onAnimationStarted(); 258 } 259 260 /** 261 * Create an ActivityOptions specifying an animation where the new 262 * activity is scaled from a small originating area of the screen to 263 * its final full representation. 264 * 265 * <p>If the Intent this is being used with has not set its 266 * {@link android.content.Intent#setSourceBounds Intent.setSourceBounds}, 267 * those bounds will be filled in for you based on the initial 268 * bounds passed in here. 269 * 270 * @param source The View that the new activity is animating from. This 271 * defines the coordinate space for <var>startX</var> and <var>startY</var>. 272 * @param startX The x starting location of the new activity, relative to <var>source</var>. 273 * @param startY The y starting location of the activity, relative to <var>source</var>. 274 * @param width The initial width of the new activity. 275 * @param height The initial height of the new activity. 276 * @return Returns a new ActivityOptions object that you can use to 277 * supply these options as the options Bundle when starting an activity. 278 */ 279 public static ActivityOptions makeScaleUpAnimation(View source, 280 int startX, int startY, int width, int height) { 281 ActivityOptions opts = new ActivityOptions(); 282 opts.mPackageName = source.getContext().getPackageName(); 283 opts.mAnimationType = ANIM_SCALE_UP; 284 int[] pts = new int[2]; 285 source.getLocationOnScreen(pts); 286 opts.mStartX = pts[0] + startX; 287 opts.mStartY = pts[1] + startY; 288 opts.mWidth = width; 289 opts.mHeight = height; 290 return opts; 291 } 292 293 /** 294 * Create an ActivityOptions specifying an animation where a thumbnail 295 * is scaled from a given position to the new activity window that is 296 * being started. 297 * 298 * <p>If the Intent this is being used with has not set its 299 * {@link android.content.Intent#setSourceBounds Intent.setSourceBounds}, 300 * those bounds will be filled in for you based on the initial 301 * thumbnail location and size provided here. 302 * 303 * @param source The View that this thumbnail is animating from. This 304 * defines the coordinate space for <var>startX</var> and <var>startY</var>. 305 * @param thumbnail The bitmap that will be shown as the initial thumbnail 306 * of the animation. 307 * @param startX The x starting location of the bitmap, relative to <var>source</var>. 308 * @param startY The y starting location of the bitmap, relative to <var>source</var>. 309 * @return Returns a new ActivityOptions object that you can use to 310 * supply these options as the options Bundle when starting an activity. 311 */ 312 public static ActivityOptions makeThumbnailScaleUpAnimation(View source, 313 Bitmap thumbnail, int startX, int startY) { 314 return makeThumbnailScaleUpAnimation(source, thumbnail, startX, startY, null); 315 } 316 317 /** 318 * Create an ActivityOptions specifying an animation where a thumbnail 319 * is scaled from a given position to the new activity window that is 320 * being started. 321 * 322 * @param source The View that this thumbnail is animating from. This 323 * defines the coordinate space for <var>startX</var> and <var>startY</var>. 324 * @param thumbnail The bitmap that will be shown as the initial thumbnail 325 * of the animation. 326 * @param startX The x starting location of the bitmap, relative to <var>source</var>. 327 * @param startY The y starting location of the bitmap, relative to <var>source</var>. 328 * @param listener Optional OnAnimationStartedListener to find out when the 329 * requested animation has started running. If for some reason the animation 330 * is not executed, the callback will happen immediately. 331 * @return Returns a new ActivityOptions object that you can use to 332 * supply these options as the options Bundle when starting an activity. 333 * @hide 334 */ 335 public static ActivityOptions makeThumbnailScaleUpAnimation(View source, 336 Bitmap thumbnail, int startX, int startY, OnAnimationStartedListener listener) { 337 return makeThumbnailAnimation(source, thumbnail, startX, startY, listener, true); 338 } 339 340 /** 341 * Create an ActivityOptions specifying an animation where an activity window 342 * is scaled from a given position to a thumbnail at a specified location. 343 * 344 * @param source The View that this thumbnail is animating to. This 345 * defines the coordinate space for <var>startX</var> and <var>startY</var>. 346 * @param thumbnail The bitmap that will be shown as the final thumbnail 347 * of the animation. 348 * @param startX The x end location of the bitmap, relative to <var>source</var>. 349 * @param startY The y end location of the bitmap, relative to <var>source</var>. 350 * @param listener Optional OnAnimationStartedListener to find out when the 351 * requested animation has started running. If for some reason the animation 352 * is not executed, the callback will happen immediately. 353 * @return Returns a new ActivityOptions object that you can use to 354 * supply these options as the options Bundle when starting an activity. 355 * @hide 356 */ 357 public static ActivityOptions makeThumbnailScaleDownAnimation(View source, 358 Bitmap thumbnail, int startX, int startY, OnAnimationStartedListener listener) { 359 return makeThumbnailAnimation(source, thumbnail, startX, startY, listener, false); 360 } 361 362 private static ActivityOptions makeThumbnailAnimation(View source, 363 Bitmap thumbnail, int startX, int startY, OnAnimationStartedListener listener, 364 boolean scaleUp) { 365 ActivityOptions opts = new ActivityOptions(); 366 opts.mPackageName = source.getContext().getPackageName(); 367 opts.mAnimationType = scaleUp ? ANIM_THUMBNAIL_SCALE_UP : ANIM_THUMBNAIL_SCALE_DOWN; 368 opts.mThumbnail = thumbnail; 369 int[] pts = new int[2]; 370 source.getLocationOnScreen(pts); 371 opts.mStartX = pts[0] + startX; 372 opts.mStartY = pts[1] + startY; 373 opts.setOnAnimationStartedListener(source.getHandler(), listener); 374 return opts; 375 } 376 377 /** 378 * Create an ActivityOptions specifying an animation where the new activity 379 * window and a thumbnail is aspect-scaled to a new location. 380 * 381 * @param source The View that this thumbnail is animating from. This 382 * defines the coordinate space for <var>startX</var> and <var>startY</var>. 383 * @param thumbnail The bitmap that will be shown as the initial thumbnail 384 * of the animation. 385 * @param startX The x starting location of the bitmap, relative to <var>source</var>. 386 * @param startY The y starting location of the bitmap, relative to <var>source</var>. 387 * @param handler If <var>listener</var> is non-null this must be a valid 388 * Handler on which to dispatch the callback; otherwise it should be null. 389 * @param listener Optional OnAnimationStartedListener to find out when the 390 * requested animation has started running. If for some reason the animation 391 * is not executed, the callback will happen immediately. 392 * @return Returns a new ActivityOptions object that you can use to 393 * supply these options as the options Bundle when starting an activity. 394 * @hide 395 */ 396 public static ActivityOptions makeThumbnailAspectScaleUpAnimation(View source, 397 Bitmap thumbnail, int startX, int startY, int targetWidth, int targetHeight, 398 Handler handler, OnAnimationStartedListener listener) { 399 return makeAspectScaledThumbnailAnimation(source, thumbnail, startX, startY, 400 targetWidth, targetHeight, handler, listener, true); 401 } 402 403 /** 404 * Create an ActivityOptions specifying an animation where the new activity 405 * window and a thumbnail is aspect-scaled to a new location. 406 * 407 * @param source The View that this thumbnail is animating to. This 408 * defines the coordinate space for <var>startX</var> and <var>startY</var>. 409 * @param thumbnail The bitmap that will be shown as the final thumbnail 410 * of the animation. 411 * @param startX The x end location of the bitmap, relative to <var>source</var>. 412 * @param startY The y end location of the bitmap, relative to <var>source</var>. 413 * @param handler If <var>listener</var> is non-null this must be a valid 414 * Handler on which to dispatch the callback; otherwise it should be null. 415 * @param listener Optional OnAnimationStartedListener to find out when the 416 * requested animation has started running. If for some reason the animation 417 * is not executed, the callback will happen immediately. 418 * @return Returns a new ActivityOptions object that you can use to 419 * supply these options as the options Bundle when starting an activity. 420 * @hide 421 */ 422 public static ActivityOptions makeThumbnailAspectScaleDownAnimation(View source, 423 Bitmap thumbnail, int startX, int startY, int targetWidth, int targetHeight, 424 Handler handler, OnAnimationStartedListener listener) { 425 return makeAspectScaledThumbnailAnimation(source, thumbnail, startX, startY, 426 targetWidth, targetHeight, handler, listener, false); 427 } 428 429 private static ActivityOptions makeAspectScaledThumbnailAnimation(View source, Bitmap thumbnail, 430 int startX, int startY, int targetWidth, int targetHeight, 431 Handler handler, OnAnimationStartedListener listener, boolean scaleUp) { 432 ActivityOptions opts = new ActivityOptions(); 433 opts.mPackageName = source.getContext().getPackageName(); 434 opts.mAnimationType = scaleUp ? ANIM_THUMBNAIL_ASPECT_SCALE_UP : 435 ANIM_THUMBNAIL_ASPECT_SCALE_DOWN; 436 opts.mThumbnail = thumbnail; 437 int[] pts = new int[2]; 438 source.getLocationOnScreen(pts); 439 opts.mStartX = pts[0] + startX; 440 opts.mStartY = pts[1] + startY; 441 opts.mWidth = targetWidth; 442 opts.mHeight = targetHeight; 443 opts.setOnAnimationStartedListener(handler, listener); 444 return opts; 445 } 446 447 /** 448 * Create an ActivityOptions to transition between Activities using cross-Activity scene 449 * animations. This method carries the position of one shared element to the started Activity. 450 * The position of <code>sharedElement</code> will be used as the epicenter for the 451 * exit Transition. The position of the shared element in the launched Activity will be the 452 * epicenter of its entering Transition. 453 * 454 * <p>This requires {@link android.view.Window#FEATURE_ACTIVITY_TRANSITIONS} to be 455 * enabled on the calling Activity to cause an exit transition. The same must be in 456 * the called Activity to get an entering transition.</p> 457 * @param activity The Activity whose window contains the shared elements. 458 * @param sharedElement The View to transition to the started Activity. 459 * @param sharedElementName The shared element name as used in the target Activity. This 460 * must not be null. 461 * @return Returns a new ActivityOptions object that you can use to 462 * supply these options as the options Bundle when starting an activity. 463 * @see android.transition.Transition#setEpicenterCallback( 464 * android.transition.Transition.EpicenterCallback) 465 */ 466 public static ActivityOptions makeSceneTransitionAnimation(Activity activity, 467 View sharedElement, String sharedElementName) { 468 return makeSceneTransitionAnimation(activity, Pair.create(sharedElement, sharedElementName)); 469 } 470 471 /** 472 * Create an ActivityOptions to transition between Activities using cross-Activity scene 473 * animations. This method carries the position of multiple shared elements to the started 474 * Activity. The position of the first element in sharedElements 475 * will be used as the epicenter for the exit Transition. The position of the associated 476 * shared element in the launched Activity will be the epicenter of its entering Transition. 477 * 478 * <p>This requires {@link android.view.Window#FEATURE_ACTIVITY_TRANSITIONS} to be 479 * enabled on the calling Activity to cause an exit transition. The same must be in 480 * the called Activity to get an entering transition.</p> 481 * @param activity The Activity whose window contains the shared elements. 482 * @param sharedElements The names of the shared elements to transfer to the called 483 * Activity and their associated Views. The Views must each have 484 * a unique shared element name. 485 * @return Returns a new ActivityOptions object that you can use to 486 * supply these options as the options Bundle when starting an activity. 487 * @see android.transition.Transition#setEpicenterCallback( 488 * android.transition.Transition.EpicenterCallback) 489 */ 490 public static ActivityOptions makeSceneTransitionAnimation(Activity activity, 491 Pair<View, String>... sharedElements) { 492 ActivityOptions opts = new ActivityOptions(); 493 if (!activity.getWindow().hasFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)) { 494 opts.mAnimationType = ANIM_DEFAULT; 495 return opts; 496 } 497 opts.mAnimationType = ANIM_SCENE_TRANSITION; 498 499 ArrayList<String> names = new ArrayList<String>(); 500 ArrayList<View> views = new ArrayList<View>(); 501 502 if (sharedElements != null) { 503 for (int i = 0; i < sharedElements.length; i++) { 504 Pair<View, String> sharedElement = sharedElements[i]; 505 String sharedElementName = sharedElement.second; 506 if (sharedElementName == null) { 507 throw new IllegalArgumentException("Shared element name must not be null"); 508 } 509 names.add(sharedElementName); 510 View view = sharedElement.first; 511 if (view == null) { 512 throw new IllegalArgumentException("Shared element must not be null"); 513 } 514 views.add(sharedElement.first); 515 } 516 } 517 518 ExitTransitionCoordinator exit = new ExitTransitionCoordinator(activity, names, names, 519 views, false); 520 opts.mTransitionReceiver = exit; 521 opts.mSharedElementNames = names; 522 opts.mIsReturning = false; 523 opts.mExitCoordinatorIndex = 524 activity.mActivityTransitionState.addExitTransitionCoordinator(exit); 525 return opts; 526 } 527 528 /** @hide */ 529 public static ActivityOptions makeSceneTransitionAnimation(Activity activity, 530 ExitTransitionCoordinator exitCoordinator, ArrayList<String> sharedElementNames, 531 int resultCode, Intent resultData) { 532 ActivityOptions opts = new ActivityOptions(); 533 opts.mAnimationType = ANIM_SCENE_TRANSITION; 534 opts.mSharedElementNames = sharedElementNames; 535 opts.mTransitionReceiver = exitCoordinator; 536 opts.mIsReturning = true; 537 opts.mResultCode = resultCode; 538 opts.mResultData = resultData; 539 opts.mExitCoordinatorIndex = 540 activity.mActivityTransitionState.addExitTransitionCoordinator(exitCoordinator); 541 return opts; 542 } 543 544 /** 545 * If set along with Intent.FLAG_ACTIVITY_NEW_DOCUMENT then the task being launched will not be 546 * presented to the user but will instead be only available through the recents task list. 547 * In addition, the new task wil be affiliated with the launching activity's task. 548 * Affiliated tasks are grouped together in the recents task list. 549 * 550 * <p>This behavior is not supported for activities with {@link 551 * android.R.styleable#AndroidManifestActivity_launchMode launchMode} values of 552 * <code>singleInstance</code> or <code>singleTask</code>. 553 */ 554 public static ActivityOptions makeTaskLaunchBehind() { 555 final ActivityOptions opts = new ActivityOptions(); 556 opts.mAnimationType = ANIM_LAUNCH_TASK_BEHIND; 557 return opts; 558 } 559 560 /** @hide */ 561 public boolean getLaunchTaskBehind() { 562 return mAnimationType == ANIM_LAUNCH_TASK_BEHIND; 563 } 564 565 private ActivityOptions() { 566 } 567 568 /** @hide */ 569 public ActivityOptions(Bundle opts) { 570 mPackageName = opts.getString(KEY_PACKAGE_NAME); 571 mAnimationType = opts.getInt(KEY_ANIM_TYPE); 572 switch (mAnimationType) { 573 case ANIM_CUSTOM: 574 mCustomEnterResId = opts.getInt(KEY_ANIM_ENTER_RES_ID, 0); 575 mCustomExitResId = opts.getInt(KEY_ANIM_EXIT_RES_ID, 0); 576 mAnimationStartedListener = IRemoteCallback.Stub.asInterface( 577 opts.getBinder(KEY_ANIM_START_LISTENER)); 578 break; 579 580 case ANIM_CUSTOM_IN_PLACE: 581 mCustomInPlaceResId = opts.getInt(KEY_ANIM_IN_PLACE_RES_ID, 0); 582 break; 583 584 case ANIM_SCALE_UP: 585 mStartX = opts.getInt(KEY_ANIM_START_X, 0); 586 mStartY = opts.getInt(KEY_ANIM_START_Y, 0); 587 mWidth = opts.getInt(KEY_ANIM_WIDTH, 0); 588 mHeight = opts.getInt(KEY_ANIM_HEIGHT, 0); 589 break; 590 591 case ANIM_THUMBNAIL_SCALE_UP: 592 case ANIM_THUMBNAIL_SCALE_DOWN: 593 case ANIM_THUMBNAIL_ASPECT_SCALE_UP: 594 case ANIM_THUMBNAIL_ASPECT_SCALE_DOWN: 595 mThumbnail = (Bitmap) opts.getParcelable(KEY_ANIM_THUMBNAIL); 596 mStartX = opts.getInt(KEY_ANIM_START_X, 0); 597 mStartY = opts.getInt(KEY_ANIM_START_Y, 0); 598 mWidth = opts.getInt(KEY_ANIM_WIDTH, 0); 599 mHeight = opts.getInt(KEY_ANIM_HEIGHT, 0); 600 mAnimationStartedListener = IRemoteCallback.Stub.asInterface( 601 opts.getBinder(KEY_ANIM_START_LISTENER)); 602 break; 603 604 case ANIM_SCENE_TRANSITION: 605 mTransitionReceiver = opts.getParcelable(KEY_TRANSITION_COMPLETE_LISTENER); 606 mIsReturning = opts.getBoolean(KEY_TRANSITION_IS_RETURNING, false); 607 mSharedElementNames = opts.getStringArrayList(KEY_TRANSITION_SHARED_ELEMENTS); 608 mResultData = opts.getParcelable(KEY_RESULT_DATA); 609 mResultCode = opts.getInt(KEY_RESULT_CODE); 610 mExitCoordinatorIndex = opts.getInt(KEY_EXIT_COORDINATOR_INDEX); 611 break; 612 } 613 } 614 615 /** @hide */ 616 public String getPackageName() { 617 return mPackageName; 618 } 619 620 /** @hide */ 621 public int getAnimationType() { 622 return mAnimationType; 623 } 624 625 /** @hide */ 626 public int getCustomEnterResId() { 627 return mCustomEnterResId; 628 } 629 630 /** @hide */ 631 public int getCustomExitResId() { 632 return mCustomExitResId; 633 } 634 635 /** @hide */ 636 public int getCustomInPlaceResId() { 637 return mCustomInPlaceResId; 638 } 639 640 /** @hide */ 641 public Bitmap getThumbnail() { 642 return mThumbnail; 643 } 644 645 /** @hide */ 646 public int getStartX() { 647 return mStartX; 648 } 649 650 /** @hide */ 651 public int getStartY() { 652 return mStartY; 653 } 654 655 /** @hide */ 656 public int getWidth() { 657 return mWidth; 658 } 659 660 /** @hide */ 661 public int getHeight() { 662 return mHeight; 663 } 664 665 /** @hide */ 666 public IRemoteCallback getOnAnimationStartListener() { 667 return mAnimationStartedListener; 668 } 669 670 /** @hide */ 671 public int getExitCoordinatorKey() { return mExitCoordinatorIndex; } 672 673 /** @hide */ 674 public void abort() { 675 if (mAnimationStartedListener != null) { 676 try { 677 mAnimationStartedListener.sendResult(null); 678 } catch (RemoteException e) { 679 } 680 } 681 } 682 683 /** @hide */ 684 public boolean isReturning() { 685 return mIsReturning; 686 } 687 688 /** @hide */ 689 public ArrayList<String> getSharedElementNames() { 690 return mSharedElementNames; 691 } 692 693 /** @hide */ 694 public ResultReceiver getResultReceiver() { return mTransitionReceiver; } 695 696 /** @hide */ 697 public int getResultCode() { return mResultCode; } 698 699 /** @hide */ 700 public Intent getResultData() { return mResultData; } 701 702 /** @hide */ 703 public static void abort(Bundle options) { 704 if (options != null) { 705 (new ActivityOptions(options)).abort(); 706 } 707 } 708 709 /** 710 * Update the current values in this ActivityOptions from those supplied 711 * in <var>otherOptions</var>. Any values 712 * defined in <var>otherOptions</var> replace those in the base options. 713 */ 714 public void update(ActivityOptions otherOptions) { 715 if (otherOptions.mPackageName != null) { 716 mPackageName = otherOptions.mPackageName; 717 } 718 mTransitionReceiver = null; 719 mSharedElementNames = null; 720 mIsReturning = false; 721 mResultData = null; 722 mResultCode = 0; 723 mExitCoordinatorIndex = 0; 724 mAnimationType = otherOptions.mAnimationType; 725 switch (otherOptions.mAnimationType) { 726 case ANIM_CUSTOM: 727 mCustomEnterResId = otherOptions.mCustomEnterResId; 728 mCustomExitResId = otherOptions.mCustomExitResId; 729 mThumbnail = null; 730 if (mAnimationStartedListener != null) { 731 try { 732 mAnimationStartedListener.sendResult(null); 733 } catch (RemoteException e) { 734 } 735 } 736 mAnimationStartedListener = otherOptions.mAnimationStartedListener; 737 break; 738 case ANIM_CUSTOM_IN_PLACE: 739 mCustomInPlaceResId = otherOptions.mCustomInPlaceResId; 740 break; 741 case ANIM_SCALE_UP: 742 mStartX = otherOptions.mStartX; 743 mStartY = otherOptions.mStartY; 744 mWidth = otherOptions.mWidth; 745 mHeight = otherOptions.mHeight; 746 if (mAnimationStartedListener != null) { 747 try { 748 mAnimationStartedListener.sendResult(null); 749 } catch (RemoteException e) { 750 } 751 } 752 mAnimationStartedListener = null; 753 break; 754 case ANIM_THUMBNAIL_SCALE_UP: 755 case ANIM_THUMBNAIL_SCALE_DOWN: 756 case ANIM_THUMBNAIL_ASPECT_SCALE_UP: 757 case ANIM_THUMBNAIL_ASPECT_SCALE_DOWN: 758 mThumbnail = otherOptions.mThumbnail; 759 mStartX = otherOptions.mStartX; 760 mStartY = otherOptions.mStartY; 761 mWidth = otherOptions.mWidth; 762 mHeight = otherOptions.mHeight; 763 if (mAnimationStartedListener != null) { 764 try { 765 mAnimationStartedListener.sendResult(null); 766 } catch (RemoteException e) { 767 } 768 } 769 mAnimationStartedListener = otherOptions.mAnimationStartedListener; 770 break; 771 case ANIM_SCENE_TRANSITION: 772 mTransitionReceiver = otherOptions.mTransitionReceiver; 773 mSharedElementNames = otherOptions.mSharedElementNames; 774 mIsReturning = otherOptions.mIsReturning; 775 mThumbnail = null; 776 mAnimationStartedListener = null; 777 mResultData = otherOptions.mResultData; 778 mResultCode = otherOptions.mResultCode; 779 mExitCoordinatorIndex = otherOptions.mExitCoordinatorIndex; 780 break; 781 } 782 } 783 784 /** 785 * Returns the created options as a Bundle, which can be passed to 786 * {@link android.content.Context#startActivity(android.content.Intent, android.os.Bundle) 787 * Context.startActivity(Intent, Bundle)} and related methods. 788 * Note that the returned Bundle is still owned by the ActivityOptions 789 * object; you must not modify it, but can supply it to the startActivity 790 * methods that take an options Bundle. 791 */ 792 public Bundle toBundle() { 793 if (mAnimationType == ANIM_DEFAULT) { 794 return null; 795 } 796 Bundle b = new Bundle(); 797 if (mPackageName != null) { 798 b.putString(KEY_PACKAGE_NAME, mPackageName); 799 } 800 b.putInt(KEY_ANIM_TYPE, mAnimationType); 801 switch (mAnimationType) { 802 case ANIM_CUSTOM: 803 b.putInt(KEY_ANIM_ENTER_RES_ID, mCustomEnterResId); 804 b.putInt(KEY_ANIM_EXIT_RES_ID, mCustomExitResId); 805 b.putBinder(KEY_ANIM_START_LISTENER, mAnimationStartedListener 806 != null ? mAnimationStartedListener.asBinder() : null); 807 break; 808 case ANIM_CUSTOM_IN_PLACE: 809 b.putInt(KEY_ANIM_IN_PLACE_RES_ID, mCustomInPlaceResId); 810 break; 811 case ANIM_SCALE_UP: 812 b.putInt(KEY_ANIM_START_X, mStartX); 813 b.putInt(KEY_ANIM_START_Y, mStartY); 814 b.putInt(KEY_ANIM_WIDTH, mWidth); 815 b.putInt(KEY_ANIM_HEIGHT, mHeight); 816 break; 817 case ANIM_THUMBNAIL_SCALE_UP: 818 case ANIM_THUMBNAIL_SCALE_DOWN: 819 case ANIM_THUMBNAIL_ASPECT_SCALE_UP: 820 case ANIM_THUMBNAIL_ASPECT_SCALE_DOWN: 821 b.putParcelable(KEY_ANIM_THUMBNAIL, mThumbnail); 822 b.putInt(KEY_ANIM_START_X, mStartX); 823 b.putInt(KEY_ANIM_START_Y, mStartY); 824 b.putInt(KEY_ANIM_WIDTH, mWidth); 825 b.putInt(KEY_ANIM_HEIGHT, mHeight); 826 b.putBinder(KEY_ANIM_START_LISTENER, mAnimationStartedListener 827 != null ? mAnimationStartedListener.asBinder() : null); 828 break; 829 case ANIM_SCENE_TRANSITION: 830 if (mTransitionReceiver != null) { 831 b.putParcelable(KEY_TRANSITION_COMPLETE_LISTENER, mTransitionReceiver); 832 } 833 b.putBoolean(KEY_TRANSITION_IS_RETURNING, mIsReturning); 834 b.putStringArrayList(KEY_TRANSITION_SHARED_ELEMENTS, mSharedElementNames); 835 b.putParcelable(KEY_RESULT_DATA, mResultData); 836 b.putInt(KEY_RESULT_CODE, mResultCode); 837 b.putInt(KEY_EXIT_COORDINATOR_INDEX, mExitCoordinatorIndex); 838 break; 839 } 840 841 return b; 842 } 843 844 /** 845 * Return the filtered options only meant to be seen by the target activity itself 846 * @hide 847 */ 848 public ActivityOptions forTargetActivity() { 849 if (mAnimationType == ANIM_SCENE_TRANSITION) { 850 final ActivityOptions result = new ActivityOptions(); 851 result.update(this); 852 return result; 853 } 854 855 return null; 856 } 857 858 } 859