diff options
| author | Adam Powell <adamp@google.com> | 2013-10-24 14:27:48 -0700 |
|---|---|---|
| committer | Adam Powell <adamp@google.com> | 2013-11-05 17:49:56 -0800 |
| commit | 18e905f42d017c4721d33bd25d7d39ef8d64b5d5 (patch) | |
| tree | f415b0677bf1f089bfa03fa85615fec197182123 /core/java/android | |
| parent | f5e99f130e46cd24f1ba53b56b2a18ad7dd0aa6c (diff) | |
| download | frameworks_base-18e905f42d017c4721d33bd25d7d39ef8d64b5d5.zip frameworks_base-18e905f42d017c4721d33bd25d7d39ef8d64b5d5.tar.gz frameworks_base-18e905f42d017c4721d33bd25d7d39ef8d64b5d5.tar.bz2 | |
Make Scenes and Transitions first-class in PhoneWindow/Themes
Add a window feature for content transitions. This implicitly creates
a Scene for each setContentView operation and runs the appropriate
transition. Applications can specify a TransitionManager XML in their
theme that will apply the appropriate transitions when these implicit
scene changes occur. Apps can specify a "to" with no "from" in a
transition to request an entrance transition for the given
content. This lays the groundwork for further full content
change/activity to activity transitions.
Change-Id: Ic815d9e0b9ce958152d70bf6ee01be075aa9fe88
Diffstat (limited to 'core/java/android')
| -rw-r--r-- | core/java/android/app/ActivityOptions.java | 179 | ||||
| -rw-r--r-- | core/java/android/transition/Scene.java | 11 | ||||
| -rw-r--r-- | core/java/android/view/Window.java | 11 |
3 files changed, 173 insertions, 28 deletions
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java index 87b1e24..44f6859 100644 --- a/core/java/android/app/ActivityOptions.java +++ b/core/java/android/app/ActivityOptions.java @@ -90,6 +90,35 @@ public class ActivityOptions { */ public static final String KEY_ANIM_START_LISTENER = "android:animStartListener"; + /** + * A string array of names for the destination scene. This defines an API in the same + * way that intent action or extra names do and should follow a similar convention: + * "com.example.scene.FOO" + * + * @hide + */ + public static final String KEY_DEST_SCENE_NAMES = "android:destSceneNames"; + + /** + * A string indicating the destination scene name that was chosen by the target. + * Used by {@link OnSceneTransitionStartedListener}. + * @hide + */ + public static final String KEY_DEST_SCENE_NAME_CHOSEN = "android:destSceneNameChosen"; + + /** + * Callback for when scene transition is started. + * @hide + */ + public static final String KEY_SCENE_TRANSITION_START_LISTENER = + "android:sceneTransitionStartListener"; + + /** + * Arguments for the scene transition about to begin. + * @hide + */ + public static final String KEY_SCENE_TRANSITION_ARGS = "android:sceneTransitionArgs"; + /** @hide */ public static final int ANIM_NONE = 0; /** @hide */ @@ -100,6 +129,8 @@ public class ActivityOptions { public static final int ANIM_THUMBNAIL_SCALE_UP = 3; /** @hide */ public static final int ANIM_THUMBNAIL_SCALE_DOWN = 4; + /** @hide */ + public static final int ANIM_SCENE_TRANSITION = 5; private String mPackageName; private int mAnimationType = ANIM_NONE; @@ -110,7 +141,10 @@ public class ActivityOptions { private int mStartY; private int mStartWidth; private int mStartHeight; + private String[] mDestSceneNames; + private Bundle mTransitionArgs; private IRemoteCallback mAnimationStartedListener; + private IRemoteCallback mSceneTransitionStartedListener; /** * Create an ActivityOptions specifying a custom animation to run when @@ -156,11 +190,12 @@ public class ActivityOptions { opts.mAnimationType = ANIM_CUSTOM; opts.mCustomEnterResId = enterResId; opts.mCustomExitResId = exitResId; - opts.setListener(handler, listener); + opts.setOnAnimationStartedListener(handler, listener); return opts; } - private void setListener(Handler handler, OnAnimationStartedListener listener) { + private void setOnAnimationStartedListener(Handler handler, + OnAnimationStartedListener listener) { if (listener != null) { final Handler h = handler; final OnAnimationStartedListener finalListener = listener; @@ -176,6 +211,24 @@ public class ActivityOptions { } } + private void setOnSceneTransitionStartedListener(Handler handler, + OnSceneTransitionStartedListener listener) { + if (listener != null) { + final Handler h = handler; + final OnSceneTransitionStartedListener l = listener; + mSceneTransitionStartedListener = new IRemoteCallback.Stub() { + @Override public void sendResult(final Bundle data) throws RemoteException { + h.post(new Runnable() { + public void run() { + l.onSceneTransitionStarted(data != null ? + data.getString(KEY_DEST_SCENE_NAME_CHOSEN) : null); + } + }); + } + }; + } + } + /** * Callback for use with {@link ActivityOptions#makeThumbnailScaleUpAnimation} * to find out when the given animation has started running. @@ -186,6 +239,15 @@ public class ActivityOptions { } /** + * Callback for use with {@link ActivityOptions#makeSceneTransitionAnimation} + * to find out when a transition is about to begin. + * @hide + */ + public interface OnSceneTransitionStartedListener { + void onSceneTransitionStarted(String destSceneName); + } + + /** * Create an ActivityOptions specifying an animation where the new * activity is scaled from a small originating area of the screen to * its final full representation. @@ -298,7 +360,23 @@ public class ActivityOptions { source.getLocationOnScreen(pts); opts.mStartX = pts[0] + startX; opts.mStartY = pts[1] + startY; - opts.setListener(source.getHandler(), listener); + opts.setOnAnimationStartedListener(source.getHandler(), listener); + return opts; + } + + /** + * Create an ActivityOptions specifying an animation where an activity window is asked + * to perform animations within the window content. + * + * @hide + */ + public static ActivityOptions makeSceneTransitionAnimation(String[] destSceneNames, + Bundle args, OnSceneTransitionStartedListener listener, Handler handler) { + ActivityOptions opts = new ActivityOptions(); + opts.mAnimationType = ANIM_SCENE_TRANSITION; + opts.mDestSceneNames = destSceneNames; + opts.mTransitionArgs = args; + opts.setOnSceneTransitionStartedListener(handler, listener); return opts; } @@ -309,23 +387,36 @@ public class ActivityOptions { public ActivityOptions(Bundle opts) { mPackageName = opts.getString(KEY_PACKAGE_NAME); mAnimationType = opts.getInt(KEY_ANIM_TYPE); - if (mAnimationType == ANIM_CUSTOM) { - mCustomEnterResId = opts.getInt(KEY_ANIM_ENTER_RES_ID, 0); - mCustomExitResId = opts.getInt(KEY_ANIM_EXIT_RES_ID, 0); - mAnimationStartedListener = IRemoteCallback.Stub.asInterface( - opts.getIBinder(KEY_ANIM_START_LISTENER)); - } else if (mAnimationType == ANIM_SCALE_UP) { - mStartX = opts.getInt(KEY_ANIM_START_X, 0); - mStartY = opts.getInt(KEY_ANIM_START_Y, 0); - mStartWidth = opts.getInt(KEY_ANIM_START_WIDTH, 0); - mStartHeight = opts.getInt(KEY_ANIM_START_HEIGHT, 0); - } else if (mAnimationType == ANIM_THUMBNAIL_SCALE_UP || - mAnimationType == ANIM_THUMBNAIL_SCALE_DOWN) { - mThumbnail = (Bitmap)opts.getParcelable(KEY_ANIM_THUMBNAIL); - mStartX = opts.getInt(KEY_ANIM_START_X, 0); - mStartY = opts.getInt(KEY_ANIM_START_Y, 0); - mAnimationStartedListener = IRemoteCallback.Stub.asInterface( - opts.getIBinder(KEY_ANIM_START_LISTENER)); + switch (mAnimationType) { + case ANIM_CUSTOM: + mCustomEnterResId = opts.getInt(KEY_ANIM_ENTER_RES_ID, 0); + mCustomExitResId = opts.getInt(KEY_ANIM_EXIT_RES_ID, 0); + mAnimationStartedListener = IRemoteCallback.Stub.asInterface( + opts.getBinder(KEY_ANIM_START_LISTENER)); + break; + + case ANIM_SCALE_UP: + mStartX = opts.getInt(KEY_ANIM_START_X, 0); + mStartY = opts.getInt(KEY_ANIM_START_Y, 0); + mStartWidth = opts.getInt(KEY_ANIM_START_WIDTH, 0); + mStartHeight = opts.getInt(KEY_ANIM_START_HEIGHT, 0); + break; + + case ANIM_THUMBNAIL_SCALE_UP: + case ANIM_THUMBNAIL_SCALE_DOWN: + mThumbnail = (Bitmap)opts.getParcelable(KEY_ANIM_THUMBNAIL); + mStartX = opts.getInt(KEY_ANIM_START_X, 0); + mStartY = opts.getInt(KEY_ANIM_START_Y, 0); + mAnimationStartedListener = IRemoteCallback.Stub.asInterface( + opts.getBinder(KEY_ANIM_START_LISTENER)); + break; + + case ANIM_SCENE_TRANSITION: + mDestSceneNames = opts.getStringArray(KEY_DEST_SCENE_NAMES); + mTransitionArgs = opts.getBundle(KEY_SCENE_TRANSITION_ARGS); + mSceneTransitionStartedListener = IRemoteCallback.Stub.asInterface( + opts.getBinder(KEY_SCENE_TRANSITION_START_LISTENER)); + break; } } @@ -375,11 +466,26 @@ public class ActivityOptions { } /** @hide */ + public String[] getDestSceneNames() { + return mDestSceneNames; + } + + /** @hide */ + public Bundle getSceneTransitionArgs() { + return mTransitionArgs; + } + + /** @hide */ public IRemoteCallback getOnAnimationStartListener() { return mAnimationStartedListener; } /** @hide */ + public IRemoteCallback getOnSceneTransitionStartedListener() { + return mSceneTransitionStartedListener; + } + + /** @hide */ public void abort() { if (mAnimationStartedListener != null) { try { @@ -411,13 +517,16 @@ public class ActivityOptions { mCustomEnterResId = otherOptions.mCustomEnterResId; mCustomExitResId = otherOptions.mCustomExitResId; mThumbnail = null; - if (otherOptions.mAnimationStartedListener != null) { + if (mAnimationStartedListener != null) { try { - otherOptions.mAnimationStartedListener.sendResult(null); + mAnimationStartedListener.sendResult(null); } catch (RemoteException e) { } } mAnimationStartedListener = otherOptions.mAnimationStartedListener; + mSceneTransitionStartedListener = null; + mTransitionArgs = null; + mDestSceneNames = null; break; case ANIM_SCALE_UP: mAnimationType = otherOptions.mAnimationType; @@ -425,13 +534,16 @@ public class ActivityOptions { mStartY = otherOptions.mStartY; mStartWidth = otherOptions.mStartWidth; mStartHeight = otherOptions.mStartHeight; - if (otherOptions.mAnimationStartedListener != null) { + if (mAnimationStartedListener != null) { try { - otherOptions.mAnimationStartedListener.sendResult(null); + mAnimationStartedListener.sendResult(null); } catch (RemoteException e) { } } mAnimationStartedListener = null; + mSceneTransitionStartedListener = null; + mTransitionArgs = null; + mDestSceneNames = null; break; case ANIM_THUMBNAIL_SCALE_UP: case ANIM_THUMBNAIL_SCALE_DOWN: @@ -439,13 +551,28 @@ public class ActivityOptions { mThumbnail = otherOptions.mThumbnail; mStartX = otherOptions.mStartX; mStartY = otherOptions.mStartY; - if (otherOptions.mAnimationStartedListener != null) { + if (mAnimationStartedListener != null) { try { - otherOptions.mAnimationStartedListener.sendResult(null); + mAnimationStartedListener.sendResult(null); } catch (RemoteException e) { } } mAnimationStartedListener = otherOptions.mAnimationStartedListener; + mSceneTransitionStartedListener = null; + mTransitionArgs = null; + mDestSceneNames = null; + break; + case ANIM_SCENE_TRANSITION: + mAnimationType = otherOptions.mAnimationType; + if (mSceneTransitionStartedListener != null) { + try { + mSceneTransitionStartedListener.sendResult(null); + } catch (RemoteException e) { + } + } + mSceneTransitionStartedListener = otherOptions.mSceneTransitionStartedListener; + mDestSceneNames = otherOptions.mDestSceneNames; + mAnimationStartedListener = null; break; } } diff --git a/core/java/android/transition/Scene.java b/core/java/android/transition/Scene.java index e1f1896..401f4c4 100644 --- a/core/java/android/transition/Scene.java +++ b/core/java/android/transition/Scene.java @@ -34,7 +34,7 @@ public final class Scene { private Context mContext; private int mLayoutId = -1; private ViewGroup mSceneRoot; - private ViewGroup mLayout; // alternative to layoutId + private View mLayout; // alternative to layoutId Runnable mEnterAction, mExitAction; /** @@ -114,6 +114,15 @@ public final class Scene { * @param layout The view hierarchy of this scene, added as a child * of sceneRoot when this scene is entered. */ + public Scene(ViewGroup sceneRoot, View layout) { + mSceneRoot = sceneRoot; + mLayout = layout; + } + + /** + * @deprecated use {@link Scene(ViewGroup, View)}. + */ + @Deprecated public Scene(ViewGroup sceneRoot, ViewGroup layout) { mSceneRoot = sceneRoot; mLayout = layout; diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java index a940f73..bddfc63 100644 --- a/core/java/android/view/Window.java +++ b/core/java/android/view/Window.java @@ -91,12 +91,21 @@ public abstract class Window { * If overlay is enabled, the action mode UI will be allowed to cover existing window content. */ public static final int FEATURE_ACTION_MODE_OVERLAY = 10; + /** + * Flag for requesting that window content changes should be represented + * with scenes and transitions. + * + * TODO Add docs + * + * @see #setContentView + */ + public static final int FEATURE_CONTENT_TRANSITIONS = 11; /** * Max value used as a feature ID * @hide */ - public static final int FEATURE_MAX = FEATURE_ACTION_MODE_OVERLAY; + public static final int FEATURE_MAX = FEATURE_CONTENT_TRANSITIONS; /** Flag for setting the progress bar's visibility to VISIBLE */ public static final int PROGRESS_VISIBILITY_ON = -1; |
