summaryrefslogtreecommitdiffstats
path: root/core/java/android
diff options
context:
space:
mode:
authorAdam Powell <adamp@google.com>2013-10-24 14:27:48 -0700
committerAdam Powell <adamp@google.com>2013-11-05 17:49:56 -0800
commit18e905f42d017c4721d33bd25d7d39ef8d64b5d5 (patch)
treef415b0677bf1f089bfa03fa85615fec197182123 /core/java/android
parentf5e99f130e46cd24f1ba53b56b2a18ad7dd0aa6c (diff)
downloadframeworks_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.java179
-rw-r--r--core/java/android/transition/Scene.java11
-rw-r--r--core/java/android/view/Window.java11
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;