ActivityOptions.java revision eabfb3a36e9469c5e219f92b39b7200104319185
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 * @param source The View that the new activity is animating from. This 151 * defines the coordinate space for <var>startX</var> and <var>startY</var>. 152 * @param startX The x starting location of the new activity, relative to <var>source</var>. 153 * @param startY The y starting location of the activity, relative to <var>source</var>. 154 * @param startWidth The initial width of the new activity. 155 * @param startWidth The initial height of the new activity. 156 * @return Returns a new ActivityOptions object that you can use to 157 * supply these options as the options Bundle when starting an activity. 158 */ 159 public static ActivityOptions makeScaleUpAnimation(View source, 160 int startX, int startY, int startWidth, int startHeight) { 161 ActivityOptions opts = new ActivityOptions(); 162 opts.mPackageName = source.getContext().getPackageName(); 163 opts.mAnimationType = ANIM_SCALE_UP; 164 int[] pts = new int[2]; 165 source.getLocationOnScreen(pts); 166 opts.mStartX = pts[0] + startX; 167 opts.mStartY = pts[1] + startY; 168 opts.mStartWidth = startWidth; 169 opts.mStartHeight = startHeight; 170 return opts; 171 } 172 173 /** 174 * Create an ActivityOptions specifying an animation where a thumbnail 175 * is scaled from a given position to the new activity window that is 176 * being started. 177 * 178 * @param source The View that this thumbnail is animating from. This 179 * defines the coordinate space for <var>startX</var> and <var>startY</var>. 180 * @param thumbnail The bitmap that will be shown as the initial thumbnail 181 * of the animation. 182 * @param startX The x starting location of the bitmap, relative to <var>source</var>. 183 * @param startY The y starting location of the bitmap, relative to <var>source</var>. 184 * @return Returns a new ActivityOptions object that you can use to 185 * supply these options as the options Bundle when starting an activity. 186 */ 187 public static ActivityOptions makeThumbnailScaleUpAnimation(View source, 188 Bitmap thumbnail, int startX, int startY) { 189 return makeThumbnailScaleUpAnimation(source, thumbnail, startX, startY, null); 190 } 191 192 /** 193 * Create an ActivityOptions specifying an animation where a thumbnail 194 * is scaled from a given position to the new activity window that is 195 * being started. 196 * 197 * @param source The View that this thumbnail is animating from. This 198 * defines the coordinate space for <var>startX</var> and <var>startY</var>. 199 * @param thumbnail The bitmap that will be shown as the initial thumbnail 200 * of the animation. 201 * @param startX The x starting location of the bitmap, relative to <var>source</var>. 202 * @param startY The y starting location of the bitmap, relative to <var>source</var>. 203 * @param listener Optional OnAnimationStartedListener to find out when the 204 * requested animation has started running. If for some reason the animation 205 * is not executed, the callback will happen immediately. 206 * @return Returns a new ActivityOptions object that you can use to 207 * supply these options as the options Bundle when starting an activity. 208 * @hide 209 */ 210 public static ActivityOptions makeThumbnailScaleUpAnimation(View source, 211 Bitmap thumbnail, int startX, int startY, OnAnimationStartedListener listener) { 212 ActivityOptions opts = new ActivityOptions(); 213 opts.mPackageName = source.getContext().getPackageName(); 214 opts.mAnimationType = ANIM_THUMBNAIL; 215 opts.mThumbnail = thumbnail; 216 int[] pts = new int[2]; 217 source.getLocationOnScreen(pts); 218 opts.mStartX = pts[0] + startX; 219 opts.mStartY = pts[1] + startY; 220 if (listener != null) { 221 final Handler h = source.getHandler(); 222 final OnAnimationStartedListener finalListener = listener; 223 opts.mAnimationStartedListener = new IRemoteCallback.Stub() { 224 @Override public void sendResult(Bundle data) throws RemoteException { 225 h.post(new Runnable() { 226 @Override public void run() { 227 finalListener.onAnimationStarted(); 228 } 229 }); 230 } 231 }; 232 } 233 return opts; 234 } 235 236 private ActivityOptions() { 237 } 238 239 /** @hide */ 240 public ActivityOptions(Bundle opts) { 241 mPackageName = opts.getString(KEY_PACKAGE_NAME); 242 mAnimationType = opts.getInt(KEY_ANIM_TYPE); 243 if (mAnimationType == ANIM_CUSTOM) { 244 mCustomEnterResId = opts.getInt(KEY_ANIM_ENTER_RES_ID, 0); 245 mCustomExitResId = opts.getInt(KEY_ANIM_EXIT_RES_ID, 0); 246 } else if (mAnimationType == ANIM_SCALE_UP) { 247 mStartX = opts.getInt(KEY_ANIM_START_X, 0); 248 mStartY = opts.getInt(KEY_ANIM_START_Y, 0); 249 mStartWidth = opts.getInt(KEY_ANIM_START_WIDTH, 0); 250 mStartHeight = opts.getInt(KEY_ANIM_START_HEIGHT, 0); 251 } else if (mAnimationType == ANIM_THUMBNAIL) { 252 mThumbnail = (Bitmap)opts.getParcelable(KEY_ANIM_THUMBNAIL); 253 mStartX = opts.getInt(KEY_ANIM_START_X, 0); 254 mStartY = opts.getInt(KEY_ANIM_START_Y, 0); 255 mAnimationStartedListener = IRemoteCallback.Stub.asInterface( 256 opts.getIBinder(KEY_ANIM_START_LISTENER)); 257 } 258 } 259 260 /** @hide */ 261 public String getPackageName() { 262 return mPackageName; 263 } 264 265 /** @hide */ 266 public int getAnimationType() { 267 return mAnimationType; 268 } 269 270 /** @hide */ 271 public int getCustomEnterResId() { 272 return mCustomEnterResId; 273 } 274 275 /** @hide */ 276 public int getCustomExitResId() { 277 return mCustomExitResId; 278 } 279 280 /** @hide */ 281 public Bitmap getThumbnail() { 282 return mThumbnail; 283 } 284 285 /** @hide */ 286 public int getStartX() { 287 return mStartX; 288 } 289 290 /** @hide */ 291 public int getStartY() { 292 return mStartY; 293 } 294 295 /** @hide */ 296 public int getStartWidth() { 297 return mStartWidth; 298 } 299 300 /** @hide */ 301 public int getStartHeight() { 302 return mStartHeight; 303 } 304 305 /** @hide */ 306 public IRemoteCallback getOnAnimationStartListener() { 307 return mAnimationStartedListener; 308 } 309 310 /** @hide */ 311 public void abort() { 312 if (mAnimationStartedListener != null) { 313 try { 314 mAnimationStartedListener.sendResult(null); 315 } catch (RemoteException e) { 316 } 317 } 318 } 319 320 /** @hide */ 321 public static void abort(Bundle options) { 322 if (options != null) { 323 (new ActivityOptions(options)).abort(); 324 } 325 } 326 327 /** 328 * Join the values in <var>otherOptions</var> in to this one. Any values 329 * defined in <var>otherOptions</var> replace those in the base options. 330 */ 331 public void join(ActivityOptions otherOptions) { 332 if (otherOptions.mPackageName != null) { 333 mPackageName = otherOptions.mPackageName; 334 } 335 switch (otherOptions.mAnimationType) { 336 case ANIM_CUSTOM: 337 mAnimationType = otherOptions.mAnimationType; 338 mCustomEnterResId = otherOptions.mCustomEnterResId; 339 mCustomExitResId = otherOptions.mCustomExitResId; 340 mThumbnail = null; 341 mAnimationStartedListener = null; 342 break; 343 case ANIM_SCALE_UP: 344 mAnimationType = otherOptions.mAnimationType; 345 mStartX = otherOptions.mStartX; 346 mStartY = otherOptions.mStartY; 347 mStartWidth = otherOptions.mStartWidth; 348 mStartHeight = otherOptions.mStartHeight; 349 break; 350 case ANIM_THUMBNAIL: 351 mAnimationType = otherOptions.mAnimationType; 352 mThumbnail = otherOptions.mThumbnail; 353 mStartX = otherOptions.mStartX; 354 mStartY = otherOptions.mStartY; 355 if (otherOptions.mAnimationStartedListener != null) { 356 try { 357 otherOptions.mAnimationStartedListener.sendResult(null); 358 } catch (RemoteException e) { 359 } 360 } 361 mAnimationStartedListener = otherOptions.mAnimationStartedListener; 362 break; 363 } 364 } 365 366 /** 367 * Returns the created options as a Bundle, which can be passed to 368 * {@link android.content.Context#startActivity(android.content.Intent, android.os.Bundle) 369 * Context.startActivity(Intent, Bundle)} and related methods. 370 * Note that the returned Bundle is still owned by the ActivityOptions 371 * object; you must not modify it, but can supply it to the startActivity 372 * methods that take an options Bundle. 373 */ 374 public Bundle toBundle() { 375 Bundle b = new Bundle(); 376 if (mPackageName != null) { 377 b.putString(KEY_PACKAGE_NAME, mPackageName); 378 } 379 switch (mAnimationType) { 380 case ANIM_CUSTOM: 381 b.putInt(KEY_ANIM_TYPE, mAnimationType); 382 b.putInt(KEY_ANIM_ENTER_RES_ID, mCustomEnterResId); 383 b.putInt(KEY_ANIM_EXIT_RES_ID, mCustomExitResId); 384 break; 385 case ANIM_SCALE_UP: 386 b.putInt(KEY_ANIM_TYPE, mAnimationType); 387 b.putInt(KEY_ANIM_START_X, mStartX); 388 b.putInt(KEY_ANIM_START_Y, mStartY); 389 b.putInt(KEY_ANIM_START_WIDTH, mStartWidth); 390 b.putInt(KEY_ANIM_START_HEIGHT, mStartHeight); 391 break; 392 case ANIM_THUMBNAIL: 393 b.putInt(KEY_ANIM_TYPE, mAnimationType); 394 b.putParcelable(KEY_ANIM_THUMBNAIL, mThumbnail); 395 b.putInt(KEY_ANIM_START_X, mStartX); 396 b.putInt(KEY_ANIM_START_Y, mStartY); 397 b.putIBinder(KEY_ANIM_START_LISTENER, mAnimationStartedListener 398 != null ? mAnimationStartedListener.asBinder() : null); 399 break; 400 } 401 return b; 402 } 403} 404