1717package android .app ;
1818
1919import android .content .Context ;
20+ import android .graphics .Bitmap ;
2021import android .os .Bundle ;
22+ import android .os .Handler ;
23+ import android .os .IRemoteCallback ;
24+ import android .os .Message ;
25+ import android .os .RemoteException ;
26+ import android .view .View ;
2127
2228/**
2329 * Helper class for building an options Bundle that can be used with
@@ -31,6 +37,12 @@ public class ActivityOptions {
3137 */
3238 public static final String KEY_PACKAGE_NAME = "android:packageName" ;
3339
40+ /**
41+ * Type of animation that arguments specify.
42+ * @hide
43+ */
44+ public static final String KEY_ANIM_TYPE = "android:animType" ;
45+
3446 /**
3547 * Custom enter animation resource ID.
3648 * @hide
@@ -43,10 +55,45 @@ public class ActivityOptions {
4355 */
4456 public static final String KEY_ANIM_EXIT_RES_ID = "android:animExitRes" ;
4557
58+ /**
59+ * Bitmap for thumbnail animation.
60+ * @hide
61+ */
62+ public static final String KEY_ANIM_THUMBNAIL = "android:animThumbnail" ;
63+
64+ /**
65+ * Start X position of thumbnail animation.
66+ * @hide
67+ */
68+ public static final String KEY_ANIM_START_X = "android:animStartX" ;
69+
70+ /**
71+ * Start Y position of thumbnail animation.
72+ * @hide
73+ */
74+ public static final String KEY_ANIM_START_Y = "android:animStartY" ;
75+
76+ /**
77+ * Callback for when animation is started.
78+ * @hide
79+ */
80+ public static final String KEY_ANIM_START_LISTENER = "android:animStartListener" ;
81+
82+ /** @hide */
83+ public static final int ANIM_NONE = 0 ;
84+ /** @hide */
85+ public static final int ANIM_CUSTOM = 1 ;
86+ /** @hide */
87+ public static final int ANIM_THUMBNAIL = 2 ;
88+
4689 private String mPackageName ;
47- private boolean mIsCustomAnimation ;
90+ private int mAnimationType = ANIM_NONE ;
4891 private int mCustomEnterResId ;
4992 private int mCustomExitResId ;
93+ private Bitmap mThumbnail ;
94+ private int mStartX ;
95+ private int mStartY ;
96+ private IRemoteCallback mAnimationStartedListener ;
5097
5198 /**
5299 * Create an ActivityOptions specifying a custom animation to run when
@@ -65,22 +112,79 @@ public static ActivityOptions makeCustomAnimation(Context context,
65112 int enterResId , int exitResId ) {
66113 ActivityOptions opts = new ActivityOptions ();
67114 opts .mPackageName = context .getPackageName ();
68- opts .mIsCustomAnimation = true ;
115+ opts .mAnimationType = ANIM_CUSTOM ;
69116 opts .mCustomEnterResId = enterResId ;
70117 opts .mCustomExitResId = exitResId ;
71118 return opts ;
72119 }
73120
121+ /**
122+ * Callback for use with {@link ActivityOptions#makeThumbnailScaleUpAnimation}
123+ * to find out when the given animation has started running.
124+ */
125+ public interface OnAnimationStartedListener {
126+ void onAnimationStarted ();
127+ }
128+
129+ /**
130+ * Create an ActivityOptions specifying an animation where a thumbnail
131+ * is scaled from a given position to the new activity window that is
132+ * being started.
133+ *
134+ * @param source The View that this thumbnail is animating from. This
135+ * defines the coordinate space for <var>startX</var> and <var>startY</var>.
136+ * @param thumbnail The bitmap that will be shown as the initial thumbnail
137+ * of the animation.
138+ * @param startX The x starting location of the bitmap, in screen coordiantes.
139+ * @param startY The y starting location of the bitmap, in screen coordinates.
140+ * @param listener Optional OnAnimationStartedListener to find out when the
141+ * requested animation has started running. If for some reason the animation
142+ * is not executed, the callback will happen immediately.
143+ * @return Returns a new ActivityOptions object that you can use to
144+ * supply these options as the options Bundle when starting an activity.
145+ */
146+ public static ActivityOptions makeThumbnailScaleUpAnimation (View source ,
147+ Bitmap thumbnail , int startX , int startY , OnAnimationStartedListener listener ) {
148+ ActivityOptions opts = new ActivityOptions ();
149+ opts .mPackageName = source .getContext ().getPackageName ();
150+ opts .mAnimationType = ANIM_THUMBNAIL ;
151+ opts .mThumbnail = thumbnail ;
152+ int [] pts = new int [2 ];
153+ source .getLocationOnScreen (pts );
154+ opts .mStartX = pts [0 ] + startX ;
155+ opts .mStartY = pts [1 ] + startY ;
156+ if (listener != null ) {
157+ final Handler h = source .getHandler ();
158+ final OnAnimationStartedListener finalListener = listener ;
159+ opts .mAnimationStartedListener = new IRemoteCallback .Stub () {
160+ @ Override public void sendResult (Bundle data ) throws RemoteException {
161+ h .post (new Runnable () {
162+ @ Override public void run () {
163+ finalListener .onAnimationStarted ();
164+ }
165+ });
166+ }
167+ };
168+ }
169+ return opts ;
170+ }
171+
74172 private ActivityOptions () {
75173 }
76174
77175 /** @hide */
78176 public ActivityOptions (Bundle opts ) {
79177 mPackageName = opts .getString (KEY_PACKAGE_NAME );
80- if ( opts .containsKey ( KEY_ANIM_ENTER_RES_ID )) {
81- mIsCustomAnimation = true ;
178+ mAnimationType = opts .getInt ( KEY_ANIM_TYPE );
179+ if ( mAnimationType == ANIM_CUSTOM ) {
82180 mCustomEnterResId = opts .getInt (KEY_ANIM_ENTER_RES_ID , 0 );
83181 mCustomExitResId = opts .getInt (KEY_ANIM_EXIT_RES_ID , 0 );
182+ } else if (mAnimationType == ANIM_THUMBNAIL ) {
183+ mThumbnail = (Bitmap )opts .getParcelable (KEY_ANIM_THUMBNAIL );
184+ mStartX = opts .getInt (KEY_ANIM_START_X , 0 );
185+ mStartY = opts .getInt (KEY_ANIM_START_Y , 0 );
186+ mAnimationStartedListener = IRemoteCallback .Stub .asInterface (
187+ opts .getIBinder (KEY_ANIM_START_LISTENER ));
84188 }
85189 }
86190
@@ -90,8 +194,8 @@ public String getPackageName() {
90194 }
91195
92196 /** @hide */
93- public boolean isCustomAnimation () {
94- return mIsCustomAnimation ;
197+ public int getAnimationType () {
198+ return mAnimationType ;
95199 }
96200
97201 /** @hide */
@@ -104,6 +208,43 @@ public int getCustomExitResId() {
104208 return mCustomExitResId ;
105209 }
106210
211+ /** @hide */
212+ public Bitmap getThumbnail () {
213+ return mThumbnail ;
214+ }
215+
216+ /** @hide */
217+ public int getStartX () {
218+ return mStartX ;
219+ }
220+
221+ /** @hide */
222+ public int getStartY () {
223+ return mStartY ;
224+ }
225+
226+ /** @hide */
227+ public IRemoteCallback getOnAnimationStartListener () {
228+ return mAnimationStartedListener ;
229+ }
230+
231+ /** @hide */
232+ public void abort () {
233+ if (mAnimationStartedListener != null ) {
234+ try {
235+ mAnimationStartedListener .sendResult (null );
236+ } catch (RemoteException e ) {
237+ }
238+ }
239+ }
240+
241+ /** @hide */
242+ public static void abort (Bundle options ) {
243+ if (options != null ) {
244+ (new ActivityOptions (options )).abort ();
245+ }
246+ }
247+
107248 /**
108249 * Join the values in <var>otherOptions</var> in to this one. Any values
109250 * defined in <var>otherOptions</var> replace those in the base options.
@@ -112,10 +253,27 @@ public void join(ActivityOptions otherOptions) {
112253 if (otherOptions .mPackageName != null ) {
113254 mPackageName = otherOptions .mPackageName ;
114255 }
115- if (otherOptions .mIsCustomAnimation ) {
116- mIsCustomAnimation = true ;
117- mCustomEnterResId = otherOptions .mCustomEnterResId ;
118- mCustomExitResId = otherOptions .mCustomExitResId ;
256+ switch (otherOptions .mAnimationType ) {
257+ case ANIM_CUSTOM :
258+ mAnimationType = otherOptions .mAnimationType ;
259+ mCustomEnterResId = otherOptions .mCustomEnterResId ;
260+ mCustomExitResId = otherOptions .mCustomExitResId ;
261+ mThumbnail = null ;
262+ mAnimationStartedListener = null ;
263+ break ;
264+ case ANIM_THUMBNAIL :
265+ mAnimationType = otherOptions .mAnimationType ;
266+ mThumbnail = otherOptions .mThumbnail ;
267+ mStartX = otherOptions .mStartX ;
268+ mStartY = otherOptions .mStartY ;
269+ if (otherOptions .mAnimationStartedListener != null ) {
270+ try {
271+ otherOptions .mAnimationStartedListener .sendResult (null );
272+ } catch (RemoteException e ) {
273+ }
274+ }
275+ mAnimationStartedListener = otherOptions .mAnimationStartedListener ;
276+ break ;
119277 }
120278 }
121279
@@ -132,9 +290,19 @@ public Bundle toBundle() {
132290 if (mPackageName != null ) {
133291 b .putString (KEY_PACKAGE_NAME , mPackageName );
134292 }
135- if (mIsCustomAnimation ) {
136- b .putInt (KEY_ANIM_ENTER_RES_ID , mCustomEnterResId );
137- b .putInt (KEY_ANIM_EXIT_RES_ID , mCustomExitResId );
293+ switch (mAnimationType ) {
294+ case ANIM_CUSTOM :
295+ b .putInt (KEY_ANIM_TYPE , mAnimationType );
296+ b .putInt (KEY_ANIM_ENTER_RES_ID , mCustomEnterResId );
297+ b .putInt (KEY_ANIM_EXIT_RES_ID , mCustomExitResId );
298+ break ;
299+ case ANIM_THUMBNAIL :
300+ b .putInt (KEY_ANIM_TYPE , mAnimationType );
301+ b .putParcelable (KEY_ANIM_THUMBNAIL , mThumbnail );
302+ b .putInt (KEY_ANIM_START_X , mStartX );
303+ b .putInt (KEY_ANIM_START_Y , mStartY );
304+ b .putIBinder (KEY_ANIM_START_LISTENER , mAnimationStartedListener
305+ != null ? mAnimationStartedListener .asBinder () : null );
138306 }
139307 return b ;
140308 }
0 commit comments