ActivityOptions.java revision d367ca88eeede24e7d9a51ae85996a9d08d734b2
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.view.View; 26 27/** 28 * Helper class for building an options Bundle that can be used with 29 * {@link android.content.Context#startActivity(android.content.Intent, android.os.Bundle) 30 * Context.startActivity(Intent, Bundle)} and related methods. 31 */ 32public class ActivityOptions { 33 /** 34 * The package name that created the options. 35 * @hide 36 */ 37 public static final String KEY_PACKAGE_NAME = "android:packageName"; 38 39 /** 40 * Type of animation that arguments specify. 41 * @hide 42 */ 43 public static final String KEY_ANIM_TYPE = "android:animType"; 44 45 /** 46 * Custom enter animation resource ID. 47 * @hide 48 */ 49 public static final String KEY_ANIM_ENTER_RES_ID = "android:animEnterRes"; 50 51 /** 52 * Custom exit animation resource ID. 53 * @hide 54 */ 55 public static final String KEY_ANIM_EXIT_RES_ID = "android:animExitRes"; 56 57 /** 58 * Bitmap for thumbnail animation. 59 * @hide 60 */ 61 public static final String KEY_ANIM_THUMBNAIL = "android:animThumbnail"; 62 63 /** 64 * Start X position of thumbnail animation. 65 * @hide 66 */ 67 public static final String KEY_ANIM_START_X = "android:animStartX"; 68 69 /** 70 * Start Y position of thumbnail animation. 71 * @hide 72 */ 73 public static final String KEY_ANIM_START_Y = "android:animStartY"; 74 75 /** 76 * Initial width of the animation. 77 * @hide 78 */ 79 public static final String KEY_ANIM_START_WIDTH = "android:animStartWidth"; 80 81 /** 82 * Initial height of the animation. 83 * @hide 84 */ 85 public static final String KEY_ANIM_START_HEIGHT = "android:animStartHeight"; 86 87 /** 88 * Callback for when animation is started. 89 * @hide 90 */ 91 public static final String KEY_ANIM_START_LISTENER = "android:animStartListener"; 92 93 /** @hide */ 94 public static final int ANIM_NONE = 0; 95 /** @hide */ 96 public static final int ANIM_CUSTOM = 1; 97 /** @hide */ 98 public static final int ANIM_SCALE_UP = 2; 99 /** @hide */ 100 public static final int ANIM_THUMBNAIL = 3; 101 102 private String mPackageName; 103 private int mAnimationType = ANIM_NONE; 104 private int mCustomEnterResId; 105 private int mCustomExitResId; 106 private Bitmap mThumbnail; 107 private int mStartX; 108 private int mStartY; 109 private int mStartWidth; 110 private int mStartHeight; 111 private IRemoteCallback mAnimationStartedListener; 112 113 /** 114 * Create an ActivityOptions specifying a custom animation to run when 115 * the activity is displayed. 116 * 117 * @param context Who is defining this. This is the application that the 118 * animation resources will be loaded from. 119 * @param enterResId A resource ID of the animation resource to use for 120 * the incoming activity. Use 0 for no animation. 121 * @param exitResId A resource ID of the animation resource to use for 122 * the outgoing activity. Use 0 for no animation. 123 * @return Returns a new ActivityOptions object that you can use to 124 * supply these options as the options Bundle when starting an activity. 125 */ 126 public static ActivityOptions makeCustomAnimation(Context context, 127 int enterResId, int exitResId) { 128 ActivityOptions opts = new ActivityOptions(); 129 opts.mPackageName = context.getPackageName(); 130 opts.mAnimationType = ANIM_CUSTOM; 131 opts.mCustomEnterResId = enterResId; 132 opts.mCustomExitResId = exitResId; 133 return opts; 134 } 135 136 /** 137 * Callback for use with {@link ActivityOptions#makeThumbnailScaleUpAnimation} 138 * to find out when the given animation has started running. 139 * @hide 140 */ 141 public interface OnAnimationStartedListener { 142 void onAnimationStarted(); 143 } 144 145 /** 146 * Create an ActivityOptions specifying an animation where the new 147 * activity is scaled from a small originating area of the screen to 148 * its final full representation. 149 * 150 * <p>If the Intent this is being used with has not set its 151 * {@link android.content.Intent#setSourceBounds Intent.setSourceBounds}, 152 * those bounds will be filled in for you based on the initial 153 * bounds passed in here. 154 * 155 * @param source The View that the new activity is animating from. This 156 * defines the coordinate space for <var>startX</var> and <var>startY</var>. 157 * @param startX The x starting location of the new activity, relative to <var>source</var>. 158 * @param startY The y starting location of the activity, relative to <var>source</var>. 159 * @param startWidth The initial width of the new activity. 160 * @param startHeight The initial height of the new activity. 161 * @return Returns a new ActivityOptions object that you can use to 162 * supply these options as the options Bundle when starting an activity. 163 */ 164 public static ActivityOptions makeScaleUpAnimation(View source, 165 int startX, int startY, int startWidth, int startHeight) { 166 ActivityOptions opts = new ActivityOptions(); 167 opts.mPackageName = source.getContext().getPackageName(); 168 opts.mAnimationType = ANIM_SCALE_UP; 169 int[] pts = new int[2]; 170 source.getLocationOnScreen(pts); 171 opts.mStartX = pts[0] + startX; 172 opts.mStartY = pts[1] + startY; 173 opts.mStartWidth = startWidth; 174 opts.mStartHeight = startHeight; 175 return opts; 176 } 177 178 /** 179 * Create an ActivityOptions specifying an animation where a thumbnail 180 * is scaled from a given position to the new activity window that is 181 * being started. 182 * 183 * <p>If the Intent this is being used with has not set its 184 * {@link android.content.Intent#setSourceBounds Intent.setSourceBounds}, 185 * those bounds will be filled in for you based on the initial 186 * thumbnail location and size provided here. 187 * 188 * @param source The View that this thumbnail is animating from. This 189 * defines the coordinate space for <var>startX</var> and <var>startY</var>. 190 * @param thumbnail The bitmap that will be shown as the initial thumbnail 191 * of the animation. 192 * @param startX The x starting location of the bitmap, relative to <var>source</var>. 193 * @param startY The y starting location of the bitmap, relative to <var>source</var>. 194 * @return Returns a new ActivityOptions object that you can use to 195 * supply these options as the options Bundle when starting an activity. 196 */ 197 public static ActivityOptions makeThumbnailScaleUpAnimation(View source, 198 Bitmap thumbnail, int startX, int startY) { 199 return makeThumbnailScaleUpAnimation(source, thumbnail, startX, startY, null); 200 } 201 202 /** 203 * Create an ActivityOptions specifying an animation where a thumbnail 204 * is scaled from a given position to the new activity window that is 205 * being started. 206 * 207 * @param source The View that this thumbnail is animating from. This 208 * defines the coordinate space for <var>startX</var> and <var>startY</var>. 209 * @param thumbnail The bitmap that will be shown as the initial thumbnail 210 * of the animation. 211 * @param startX The x starting location of the bitmap, relative to <var>source</var>. 212 * @param startY The y starting location of the bitmap, relative to <var>source</var>. 213 * @param listener Optional OnAnimationStartedListener to find out when the 214 * requested animation has started running. If for some reason the animation 215 * is not executed, the callback will happen immediately. 216 * @return Returns a new ActivityOptions object that you can use to 217 * supply these options as the options Bundle when starting an activity. 218 * @hide 219 */ 220 public static ActivityOptions makeThumbnailScaleUpAnimation(View source, 221 Bitmap thumbnail, int startX, int startY, OnAnimationStartedListener listener) { 222 ActivityOptions opts = new ActivityOptions(); 223 opts.mPackageName = source.getContext().getPackageName(); 224 opts.mAnimationType = ANIM_THUMBNAIL; 225 opts.mThumbnail = thumbnail; 226 int[] pts = new int[2]; 227 source.getLocationOnScreen(pts); 228 opts.mStartX = pts[0] + startX; 229 opts.mStartY = pts[1] + startY; 230 if (listener != null) { 231 final Handler h = source.getHandler(); 232 final OnAnimationStartedListener finalListener = listener; 233 opts.mAnimationStartedListener = new IRemoteCallback.Stub() { 234 @Override public void sendResult(Bundle data) throws RemoteException { 235 h.post(new Runnable() { 236 @Override public void run() { 237 finalListener.onAnimationStarted(); 238 } 239 }); 240 } 241 }; 242 } 243 return opts; 244 } 245 246 private ActivityOptions() { 247 } 248 249 /** @hide */ 250 public ActivityOptions(Bundle opts) { 251 mPackageName = opts.getString(KEY_PACKAGE_NAME); 252 mAnimationType = opts.getInt(KEY_ANIM_TYPE); 253 if (mAnimationType == ANIM_CUSTOM) { 254 mCustomEnterResId = opts.getInt(KEY_ANIM_ENTER_RES_ID, 0); 255 mCustomExitResId = opts.getInt(KEY_ANIM_EXIT_RES_ID, 0); 256 } else if (mAnimationType == ANIM_SCALE_UP) { 257 mStartX = opts.getInt(KEY_ANIM_START_X, 0); 258 mStartY = opts.getInt(KEY_ANIM_START_Y, 0); 259 mStartWidth = opts.getInt(KEY_ANIM_START_WIDTH, 0); 260 mStartHeight = opts.getInt(KEY_ANIM_START_HEIGHT, 0); 261 } else if (mAnimationType == ANIM_THUMBNAIL) { 262 mThumbnail = (Bitmap)opts.getParcelable(KEY_ANIM_THUMBNAIL); 263 mStartX = opts.getInt(KEY_ANIM_START_X, 0); 264 mStartY = opts.getInt(KEY_ANIM_START_Y, 0); 265 mAnimationStartedListener = IRemoteCallback.Stub.asInterface( 266 opts.getIBinder(KEY_ANIM_START_LISTENER)); 267 } 268 } 269 270 /** @hide */ 271 public String getPackageName() { 272 return mPackageName; 273 } 274 275 /** @hide */ 276 public int getAnimationType() { 277 return mAnimationType; 278 } 279 280 /** @hide */ 281 public int getCustomEnterResId() { 282 return mCustomEnterResId; 283 } 284 285 /** @hide */ 286 public int getCustomExitResId() { 287 return mCustomExitResId; 288 } 289 290 /** @hide */ 291 public Bitmap getThumbnail() { 292 return mThumbnail; 293 } 294 295 /** @hide */ 296 public int getStartX() { 297 return mStartX; 298 } 299 300 /** @hide */ 301 public int getStartY() { 302 return mStartY; 303 } 304 305 /** @hide */ 306 public int getStartWidth() { 307 return mStartWidth; 308 } 309 310 /** @hide */ 311 public int getStartHeight() { 312 return mStartHeight; 313 } 314 315 /** @hide */ 316 public IRemoteCallback getOnAnimationStartListener() { 317 return mAnimationStartedListener; 318 } 319 320 /** @hide */ 321 public void abort() { 322 if (mAnimationStartedListener != null) { 323 try { 324 mAnimationStartedListener.sendResult(null); 325 } catch (RemoteException e) { 326 } 327 } 328 } 329 330 /** @hide */ 331 public static void abort(Bundle options) { 332 if (options != null) { 333 (new ActivityOptions(options)).abort(); 334 } 335 } 336 337 /** 338 * Update the current values in this ActivityOptions from those supplied 339 * in <var>otherOptions</var>. Any values 340 * defined in <var>otherOptions</var> replace those in the base options. 341 */ 342 public void update(ActivityOptions otherOptions) { 343 if (otherOptions.mPackageName != null) { 344 mPackageName = otherOptions.mPackageName; 345 } 346 switch (otherOptions.mAnimationType) { 347 case ANIM_CUSTOM: 348 mAnimationType = otherOptions.mAnimationType; 349 mCustomEnterResId = otherOptions.mCustomEnterResId; 350 mCustomExitResId = otherOptions.mCustomExitResId; 351 mThumbnail = null; 352 mAnimationStartedListener = null; 353 break; 354 case ANIM_SCALE_UP: 355 mAnimationType = otherOptions.mAnimationType; 356 mStartX = otherOptions.mStartX; 357 mStartY = otherOptions.mStartY; 358 mStartWidth = otherOptions.mStartWidth; 359 mStartHeight = otherOptions.mStartHeight; 360 break; 361 case ANIM_THUMBNAIL: 362 mAnimationType = otherOptions.mAnimationType; 363 mThumbnail = otherOptions.mThumbnail; 364 mStartX = otherOptions.mStartX; 365 mStartY = otherOptions.mStartY; 366 if (otherOptions.mAnimationStartedListener != null) { 367 try { 368 otherOptions.mAnimationStartedListener.sendResult(null); 369 } catch (RemoteException e) { 370 } 371 } 372 mAnimationStartedListener = otherOptions.mAnimationStartedListener; 373 break; 374 } 375 } 376 377 /** 378 * Returns the created options as a Bundle, which can be passed to 379 * {@link android.content.Context#startActivity(android.content.Intent, android.os.Bundle) 380 * Context.startActivity(Intent, Bundle)} and related methods. 381 * Note that the returned Bundle is still owned by the ActivityOptions 382 * object; you must not modify it, but can supply it to the startActivity 383 * methods that take an options Bundle. 384 */ 385 public Bundle toBundle() { 386 Bundle b = new Bundle(); 387 if (mPackageName != null) { 388 b.putString(KEY_PACKAGE_NAME, mPackageName); 389 } 390 switch (mAnimationType) { 391 case ANIM_CUSTOM: 392 b.putInt(KEY_ANIM_TYPE, mAnimationType); 393 b.putInt(KEY_ANIM_ENTER_RES_ID, mCustomEnterResId); 394 b.putInt(KEY_ANIM_EXIT_RES_ID, mCustomExitResId); 395 break; 396 case ANIM_SCALE_UP: 397 b.putInt(KEY_ANIM_TYPE, mAnimationType); 398 b.putInt(KEY_ANIM_START_X, mStartX); 399 b.putInt(KEY_ANIM_START_Y, mStartY); 400 b.putInt(KEY_ANIM_START_WIDTH, mStartWidth); 401 b.putInt(KEY_ANIM_START_HEIGHT, mStartHeight); 402 break; 403 case ANIM_THUMBNAIL: 404 b.putInt(KEY_ANIM_TYPE, mAnimationType); 405 b.putParcelable(KEY_ANIM_THUMBNAIL, mThumbnail); 406 b.putInt(KEY_ANIM_START_X, mStartX); 407 b.putInt(KEY_ANIM_START_Y, mStartY); 408 b.putIBinder(KEY_ANIM_START_LISTENER, mAnimationStartedListener 409 != null ? mAnimationStartedListener.asBinder() : null); 410 break; 411 } 412 return b; 413 } 414} 415