ActivityOptions.java revision 044d52934e57a337665f707aa4be1d423ee3fb29
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.content.Intent; 21import android.graphics.Bitmap; 22import android.os.Bundle; 23import android.os.Handler; 24import android.os.IRemoteCallback; 25import android.os.RemoteException; 26import android.os.ResultReceiver; 27import android.util.Pair; 28import android.view.View; 29import android.view.Window; 30 31import 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 */ 38public 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 listener Optional OnAnimationStartedListener to find out when the 388 * requested animation has started running. If for some reason the animation 389 * is not executed, the callback will happen immediately. 390 * @return Returns a new ActivityOptions object that you can use to 391 * supply these options as the options Bundle when starting an activity. 392 * @hide 393 */ 394 public static ActivityOptions makeThumbnailAspectScaleUpAnimation(View source, 395 Bitmap thumbnail, int startX, int startY, int targetWidth, int targetHeight, 396 OnAnimationStartedListener listener) { 397 return makeAspectScaledThumbnailAnimation(source, thumbnail, startX, startY, 398 targetWidth, targetHeight, listener, true); 399 } 400 401 /** 402 * Create an ActivityOptions specifying an animation where the new activity 403 * window and a thumbnail is aspect-scaled to a new location. 404 * 405 * @param source The View that this thumbnail is animating to. This 406 * defines the coordinate space for <var>startX</var> and <var>startY</var>. 407 * @param thumbnail The bitmap that will be shown as the final thumbnail 408 * of the animation. 409 * @param startX The x end location of the bitmap, relative to <var>source</var>. 410 * @param startY The y end location of the bitmap, relative to <var>source</var>. 411 * @param listener Optional OnAnimationStartedListener to find out when the 412 * requested animation has started running. If for some reason the animation 413 * is not executed, the callback will happen immediately. 414 * @return Returns a new ActivityOptions object that you can use to 415 * supply these options as the options Bundle when starting an activity. 416 * @hide 417 */ 418 public static ActivityOptions makeThumbnailAspectScaleDownAnimation(View source, 419 Bitmap thumbnail, int startX, int startY, int targetWidth, int targetHeight, 420 OnAnimationStartedListener listener) { 421 return makeAspectScaledThumbnailAnimation(source, thumbnail, startX, startY, 422 targetWidth, targetHeight, listener, false); 423 } 424 425 private static ActivityOptions makeAspectScaledThumbnailAnimation(View source, Bitmap thumbnail, 426 int startX, int startY, int targetWidth, int targetHeight, 427 OnAnimationStartedListener listener, boolean scaleUp) { 428 ActivityOptions opts = new ActivityOptions(); 429 opts.mPackageName = source.getContext().getPackageName(); 430 opts.mAnimationType = scaleUp ? ANIM_THUMBNAIL_ASPECT_SCALE_UP : 431 ANIM_THUMBNAIL_ASPECT_SCALE_DOWN; 432 opts.mThumbnail = thumbnail; 433 int[] pts = new int[2]; 434 source.getLocationOnScreen(pts); 435 opts.mStartX = pts[0] + startX; 436 opts.mStartY = pts[1] + startY; 437 opts.mWidth = targetWidth; 438 opts.mHeight = targetHeight; 439 opts.setOnAnimationStartedListener(source.getHandler(), listener); 440 return opts; 441 } 442 443 /** 444 * Create an ActivityOptions to transition between Activities using cross-Activity scene 445 * animations. This method carries the position of one shared element to the started Activity. 446 * The position of <code>sharedElement</code> will be used as the epicenter for the 447 * exit Transition. The position of the shared element in the launched Activity will be the 448 * epicenter of its entering Transition. 449 * 450 * <p>This requires {@link android.view.Window#FEATURE_ACTIVITY_TRANSITIONS} to be 451 * enabled on the calling Activity to cause an exit transition. The same must be in 452 * the called Activity to get an entering transition.</p> 453 * @param activity The Activity whose window contains the shared elements. 454 * @param sharedElement The View to transition to the started Activity. 455 * @param sharedElementName The shared element name as used in the target Activity. This 456 * must not be null. 457 * @return Returns a new ActivityOptions object that you can use to 458 * supply these options as the options Bundle when starting an activity. 459 * @see android.transition.Transition#setEpicenterCallback( 460 * android.transition.Transition.EpicenterCallback) 461 */ 462 public static ActivityOptions makeSceneTransitionAnimation(Activity activity, 463 View sharedElement, String sharedElementName) { 464 return makeSceneTransitionAnimation(activity, Pair.create(sharedElement, sharedElementName)); 465 } 466 467 /** 468 * Create an ActivityOptions to transition between Activities using cross-Activity scene 469 * animations. This method carries the position of multiple shared elements to the started 470 * Activity. The position of the first element in sharedElements 471 * will be used as the epicenter for the exit Transition. The position of the associated 472 * shared element in the launched Activity will be the epicenter of its entering Transition. 473 * 474 * <p>This requires {@link android.view.Window#FEATURE_ACTIVITY_TRANSITIONS} to be 475 * enabled on the calling Activity to cause an exit transition. The same must be in 476 * the called Activity to get an entering transition.</p> 477 * @param activity The Activity whose window contains the shared elements. 478 * @param sharedElements The names of the shared elements to transfer to the called 479 * Activity and their associated Views. The Views must each have 480 * a unique shared element name. 481 * @return Returns a new ActivityOptions object that you can use to 482 * supply these options as the options Bundle when starting an activity. 483 * @see android.transition.Transition#setEpicenterCallback( 484 * android.transition.Transition.EpicenterCallback) 485 */ 486 public static ActivityOptions makeSceneTransitionAnimation(Activity activity, 487 Pair<View, String>... sharedElements) { 488 ActivityOptions opts = new ActivityOptions(); 489 if (!activity.getWindow().hasFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)) { 490 opts.mAnimationType = ANIM_DEFAULT; 491 return opts; 492 } 493 opts.mAnimationType = ANIM_SCENE_TRANSITION; 494 495 ArrayList<String> names = new ArrayList<String>(); 496 ArrayList<View> views = new ArrayList<View>(); 497 498 if (sharedElements != null) { 499 for (int i = 0; i < sharedElements.length; i++) { 500 Pair<View, String> sharedElement = sharedElements[i]; 501 String sharedElementName = sharedElement.second; 502 if (sharedElementName == null) { 503 throw new IllegalArgumentException("Shared element name must not be null"); 504 } 505 names.add(sharedElementName); 506 View view = sharedElement.first; 507 if (view == null) { 508 throw new IllegalArgumentException("Shared element must not be null"); 509 } 510 views.add(sharedElement.first); 511 } 512 } 513 514 ExitTransitionCoordinator exit = new ExitTransitionCoordinator(activity, names, names, 515 views, false); 516 opts.mTransitionReceiver = exit; 517 opts.mSharedElementNames = names; 518 opts.mIsReturning = false; 519 opts.mExitCoordinatorIndex = 520 activity.mActivityTransitionState.addExitTransitionCoordinator(exit); 521 return opts; 522 } 523 524 /** @hide */ 525 public static ActivityOptions makeSceneTransitionAnimation(Activity activity, 526 ExitTransitionCoordinator exitCoordinator, ArrayList<String> sharedElementNames, 527 int resultCode, Intent resultData) { 528 ActivityOptions opts = new ActivityOptions(); 529 opts.mAnimationType = ANIM_SCENE_TRANSITION; 530 opts.mSharedElementNames = sharedElementNames; 531 opts.mTransitionReceiver = exitCoordinator; 532 opts.mIsReturning = true; 533 opts.mResultCode = resultCode; 534 opts.mResultData = resultData; 535 opts.mExitCoordinatorIndex = 536 activity.mActivityTransitionState.addExitTransitionCoordinator(exitCoordinator); 537 return opts; 538 } 539 540 /** 541 * If set along with Intent.FLAG_ACTIVITY_NEW_DOCUMENT then the task being launched will not be 542 * presented to the user but will instead be only available through the recents task list. 543 * In addition, the new task wil be affiliated with the launching activity's task. 544 * Affiliated tasks are grouped together in the recents task list. 545 * 546 * <p>This behavior is not supported for activities with {@link 547 * android.R.styleable#AndroidManifestActivity_launchMode launchMode} values of 548 * <code>singleInstance</code> or <code>singleTask</code>. 549 */ 550 public static ActivityOptions makeTaskLaunchBehind() { 551 final ActivityOptions opts = new ActivityOptions(); 552 opts.mAnimationType = ANIM_LAUNCH_TASK_BEHIND; 553 return opts; 554 } 555 556 /** @hide */ 557 public boolean getLaunchTaskBehind() { 558 return mAnimationType == ANIM_LAUNCH_TASK_BEHIND; 559 } 560 561 private ActivityOptions() { 562 } 563 564 /** @hide */ 565 public ActivityOptions(Bundle opts) { 566 mPackageName = opts.getString(KEY_PACKAGE_NAME); 567 mAnimationType = opts.getInt(KEY_ANIM_TYPE); 568 switch (mAnimationType) { 569 case ANIM_CUSTOM: 570 mCustomEnterResId = opts.getInt(KEY_ANIM_ENTER_RES_ID, 0); 571 mCustomExitResId = opts.getInt(KEY_ANIM_EXIT_RES_ID, 0); 572 mAnimationStartedListener = IRemoteCallback.Stub.asInterface( 573 opts.getBinder(KEY_ANIM_START_LISTENER)); 574 break; 575 576 case ANIM_CUSTOM_IN_PLACE: 577 mCustomInPlaceResId = opts.getInt(KEY_ANIM_IN_PLACE_RES_ID, 0); 578 break; 579 580 case ANIM_SCALE_UP: 581 mStartX = opts.getInt(KEY_ANIM_START_X, 0); 582 mStartY = opts.getInt(KEY_ANIM_START_Y, 0); 583 mWidth = opts.getInt(KEY_ANIM_WIDTH, 0); 584 mHeight = opts.getInt(KEY_ANIM_HEIGHT, 0); 585 break; 586 587 case ANIM_THUMBNAIL_SCALE_UP: 588 case ANIM_THUMBNAIL_SCALE_DOWN: 589 case ANIM_THUMBNAIL_ASPECT_SCALE_UP: 590 case ANIM_THUMBNAIL_ASPECT_SCALE_DOWN: 591 mThumbnail = (Bitmap) opts.getParcelable(KEY_ANIM_THUMBNAIL); 592 mStartX = opts.getInt(KEY_ANIM_START_X, 0); 593 mStartY = opts.getInt(KEY_ANIM_START_Y, 0); 594 mWidth = opts.getInt(KEY_ANIM_WIDTH, 0); 595 mHeight = opts.getInt(KEY_ANIM_HEIGHT, 0); 596 mAnimationStartedListener = IRemoteCallback.Stub.asInterface( 597 opts.getBinder(KEY_ANIM_START_LISTENER)); 598 break; 599 600 case ANIM_SCENE_TRANSITION: 601 mTransitionReceiver = opts.getParcelable(KEY_TRANSITION_COMPLETE_LISTENER); 602 mIsReturning = opts.getBoolean(KEY_TRANSITION_IS_RETURNING, false); 603 mSharedElementNames = opts.getStringArrayList(KEY_TRANSITION_SHARED_ELEMENTS); 604 mResultData = opts.getParcelable(KEY_RESULT_DATA); 605 mResultCode = opts.getInt(KEY_RESULT_CODE); 606 mExitCoordinatorIndex = opts.getInt(KEY_EXIT_COORDINATOR_INDEX); 607 break; 608 } 609 } 610 611 /** @hide */ 612 public String getPackageName() { 613 return mPackageName; 614 } 615 616 /** @hide */ 617 public int getAnimationType() { 618 return mAnimationType; 619 } 620 621 /** @hide */ 622 public int getCustomEnterResId() { 623 return mCustomEnterResId; 624 } 625 626 /** @hide */ 627 public int getCustomExitResId() { 628 return mCustomExitResId; 629 } 630 631 /** @hide */ 632 public int getCustomInPlaceResId() { 633 return mCustomInPlaceResId; 634 } 635 636 /** @hide */ 637 public Bitmap getThumbnail() { 638 return mThumbnail; 639 } 640 641 /** @hide */ 642 public int getStartX() { 643 return mStartX; 644 } 645 646 /** @hide */ 647 public int getStartY() { 648 return mStartY; 649 } 650 651 /** @hide */ 652 public int getWidth() { 653 return mWidth; 654 } 655 656 /** @hide */ 657 public int getHeight() { 658 return mHeight; 659 } 660 661 /** @hide */ 662 public IRemoteCallback getOnAnimationStartListener() { 663 return mAnimationStartedListener; 664 } 665 666 /** @hide */ 667 public int getExitCoordinatorKey() { return mExitCoordinatorIndex; } 668 669 /** @hide */ 670 public void abort() { 671 if (mAnimationStartedListener != null) { 672 try { 673 mAnimationStartedListener.sendResult(null); 674 } catch (RemoteException e) { 675 } 676 } 677 } 678 679 /** @hide */ 680 public boolean isReturning() { 681 return mIsReturning; 682 } 683 684 /** @hide */ 685 public ArrayList<String> getSharedElementNames() { 686 return mSharedElementNames; 687 } 688 689 /** @hide */ 690 public ResultReceiver getResultReceiver() { return mTransitionReceiver; } 691 692 /** @hide */ 693 public int getResultCode() { return mResultCode; } 694 695 /** @hide */ 696 public Intent getResultData() { return mResultData; } 697 698 /** @hide */ 699 public static void abort(Bundle options) { 700 if (options != null) { 701 (new ActivityOptions(options)).abort(); 702 } 703 } 704 705 /** 706 * Update the current values in this ActivityOptions from those supplied 707 * in <var>otherOptions</var>. Any values 708 * defined in <var>otherOptions</var> replace those in the base options. 709 */ 710 public void update(ActivityOptions otherOptions) { 711 if (otherOptions.mPackageName != null) { 712 mPackageName = otherOptions.mPackageName; 713 } 714 mTransitionReceiver = null; 715 mSharedElementNames = null; 716 mIsReturning = false; 717 mResultData = null; 718 mResultCode = 0; 719 mExitCoordinatorIndex = 0; 720 mAnimationType = otherOptions.mAnimationType; 721 switch (otherOptions.mAnimationType) { 722 case ANIM_CUSTOM: 723 mCustomEnterResId = otherOptions.mCustomEnterResId; 724 mCustomExitResId = otherOptions.mCustomExitResId; 725 mThumbnail = null; 726 if (mAnimationStartedListener != null) { 727 try { 728 mAnimationStartedListener.sendResult(null); 729 } catch (RemoteException e) { 730 } 731 } 732 mAnimationStartedListener = otherOptions.mAnimationStartedListener; 733 break; 734 case ANIM_CUSTOM_IN_PLACE: 735 mCustomInPlaceResId = otherOptions.mCustomInPlaceResId; 736 break; 737 case ANIM_SCALE_UP: 738 mStartX = otherOptions.mStartX; 739 mStartY = otherOptions.mStartY; 740 mWidth = otherOptions.mWidth; 741 mHeight = otherOptions.mHeight; 742 if (mAnimationStartedListener != null) { 743 try { 744 mAnimationStartedListener.sendResult(null); 745 } catch (RemoteException e) { 746 } 747 } 748 mAnimationStartedListener = null; 749 break; 750 case ANIM_THUMBNAIL_SCALE_UP: 751 case ANIM_THUMBNAIL_SCALE_DOWN: 752 case ANIM_THUMBNAIL_ASPECT_SCALE_UP: 753 case ANIM_THUMBNAIL_ASPECT_SCALE_DOWN: 754 mThumbnail = otherOptions.mThumbnail; 755 mStartX = otherOptions.mStartX; 756 mStartY = otherOptions.mStartY; 757 mWidth = otherOptions.mWidth; 758 mHeight = otherOptions.mHeight; 759 if (mAnimationStartedListener != null) { 760 try { 761 mAnimationStartedListener.sendResult(null); 762 } catch (RemoteException e) { 763 } 764 } 765 mAnimationStartedListener = otherOptions.mAnimationStartedListener; 766 break; 767 case ANIM_SCENE_TRANSITION: 768 mTransitionReceiver = otherOptions.mTransitionReceiver; 769 mSharedElementNames = otherOptions.mSharedElementNames; 770 mIsReturning = otherOptions.mIsReturning; 771 mThumbnail = null; 772 mAnimationStartedListener = null; 773 mResultData = otherOptions.mResultData; 774 mResultCode = otherOptions.mResultCode; 775 mExitCoordinatorIndex = otherOptions.mExitCoordinatorIndex; 776 break; 777 } 778 } 779 780 /** 781 * Returns the created options as a Bundle, which can be passed to 782 * {@link android.content.Context#startActivity(android.content.Intent, android.os.Bundle) 783 * Context.startActivity(Intent, Bundle)} and related methods. 784 * Note that the returned Bundle is still owned by the ActivityOptions 785 * object; you must not modify it, but can supply it to the startActivity 786 * methods that take an options Bundle. 787 */ 788 public Bundle toBundle() { 789 if (mAnimationType == ANIM_DEFAULT) { 790 return null; 791 } 792 Bundle b = new Bundle(); 793 if (mPackageName != null) { 794 b.putString(KEY_PACKAGE_NAME, mPackageName); 795 } 796 b.putInt(KEY_ANIM_TYPE, mAnimationType); 797 switch (mAnimationType) { 798 case ANIM_CUSTOM: 799 b.putInt(KEY_ANIM_ENTER_RES_ID, mCustomEnterResId); 800 b.putInt(KEY_ANIM_EXIT_RES_ID, mCustomExitResId); 801 b.putBinder(KEY_ANIM_START_LISTENER, mAnimationStartedListener 802 != null ? mAnimationStartedListener.asBinder() : null); 803 break; 804 case ANIM_CUSTOM_IN_PLACE: 805 b.putInt(KEY_ANIM_IN_PLACE_RES_ID, mCustomInPlaceResId); 806 break; 807 case ANIM_SCALE_UP: 808 b.putInt(KEY_ANIM_START_X, mStartX); 809 b.putInt(KEY_ANIM_START_Y, mStartY); 810 b.putInt(KEY_ANIM_WIDTH, mWidth); 811 b.putInt(KEY_ANIM_HEIGHT, mHeight); 812 break; 813 case ANIM_THUMBNAIL_SCALE_UP: 814 case ANIM_THUMBNAIL_SCALE_DOWN: 815 case ANIM_THUMBNAIL_ASPECT_SCALE_UP: 816 case ANIM_THUMBNAIL_ASPECT_SCALE_DOWN: 817 b.putParcelable(KEY_ANIM_THUMBNAIL, mThumbnail); 818 b.putInt(KEY_ANIM_START_X, mStartX); 819 b.putInt(KEY_ANIM_START_Y, mStartY); 820 b.putInt(KEY_ANIM_WIDTH, mWidth); 821 b.putInt(KEY_ANIM_HEIGHT, mHeight); 822 b.putBinder(KEY_ANIM_START_LISTENER, mAnimationStartedListener 823 != null ? mAnimationStartedListener.asBinder() : null); 824 break; 825 case ANIM_SCENE_TRANSITION: 826 if (mTransitionReceiver != null) { 827 b.putParcelable(KEY_TRANSITION_COMPLETE_LISTENER, mTransitionReceiver); 828 } 829 b.putBoolean(KEY_TRANSITION_IS_RETURNING, mIsReturning); 830 b.putStringArrayList(KEY_TRANSITION_SHARED_ELEMENTS, mSharedElementNames); 831 b.putParcelable(KEY_RESULT_DATA, mResultData); 832 b.putInt(KEY_RESULT_CODE, mResultCode); 833 b.putInt(KEY_EXIT_COORDINATOR_INDEX, mExitCoordinatorIndex); 834 break; 835 } 836 837 return b; 838 } 839 840 /** 841 * Return the filtered options only meant to be seen by the target activity itself 842 * @hide 843 */ 844 public ActivityOptions forTargetActivity() { 845 if (mAnimationType == ANIM_SCENE_TRANSITION) { 846 final ActivityOptions result = new ActivityOptions(); 847 result.update(this); 848 return result; 849 } 850 851 return null; 852 } 853 854} 855