summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/current.txt13
-rw-r--r--core/java/android/view/transition/Crossfade.java126
-rw-r--r--core/java/android/view/transition/Fade.java124
-rw-r--r--core/java/android/view/transition/Move.java115
-rw-r--r--core/java/android/view/transition/Recolor.java46
-rw-r--r--core/java/android/view/transition/Rotate.java17
-rw-r--r--core/java/android/view/transition/Slide.java20
-rw-r--r--core/java/android/view/transition/TextChange.java23
-rw-r--r--core/java/android/view/transition/Transition.java117
-rw-r--r--core/java/android/view/transition/TransitionGroup.java70
-rw-r--r--core/java/android/view/transition/TransitionValues.java6
-rw-r--r--core/java/android/view/transition/Visibility.java62
-rw-r--r--tests/TransitionTests/AndroidManifest.xml7
-rw-r--r--tests/TransitionTests/res/layout/hierarchical_move.xml46
-rw-r--r--tests/TransitionTests/res/values/strings.xml6
-rw-r--r--tests/TransitionTests/src/com/android/transitiontests/HierarchicalMove.java104
16 files changed, 365 insertions, 537 deletions
diff --git a/api/current.txt b/api/current.txt
index 481521e2498e..7281d011bf12 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -18389,7 +18389,6 @@ package android.print.pdf {
public final class PdfDocument {
method public void close();
- method protected final void finalize() throws java.lang.Throwable;
method public void finishPage(android.print.pdf.PdfDocument.Page);
method public java.util.List<android.print.pdf.PdfDocument.PageInfo> getPages();
method public static android.print.pdf.PdfDocument open();
@@ -28524,7 +28523,6 @@ package android.view.transition {
method protected void captureValues(android.view.transition.TransitionValues, boolean);
method public int getFadeBehavior();
method public int getResizeBehavior();
- method protected android.animation.Animator play(android.view.ViewGroup, android.view.transition.TransitionValues, android.view.transition.TransitionValues);
method public void setFadeBehavior(int);
method public void setResizeBehavior(int);
field public static final int FADE_BEHAVIOR_CROSSFADE = 0; // 0x0
@@ -28543,7 +28541,6 @@ package android.view.transition {
public class Move extends android.view.transition.Transition {
ctor public Move();
method protected void captureValues(android.view.transition.TransitionValues, boolean);
- method protected android.animation.Animator play(android.view.ViewGroup, android.view.transition.TransitionValues, android.view.transition.TransitionValues);
method public void setReparent(boolean);
method public void setResizeClip(boolean);
}
@@ -28551,13 +28548,11 @@ package android.view.transition {
public class Recolor extends android.view.transition.Transition {
ctor public Recolor();
method protected void captureValues(android.view.transition.TransitionValues, boolean);
- method protected android.animation.Animator play(android.view.ViewGroup, android.view.transition.TransitionValues, android.view.transition.TransitionValues);
}
public class Rotate extends android.view.transition.Transition {
ctor public Rotate();
method protected void captureValues(android.view.transition.TransitionValues, boolean);
- method protected android.animation.Animator play(android.view.ViewGroup, android.view.transition.TransitionValues, android.view.transition.TransitionValues);
}
public final class Scene {
@@ -28578,7 +28573,6 @@ package android.view.transition {
public class TextChange extends android.view.transition.Transition {
ctor public TextChange();
method protected void captureValues(android.view.transition.TransitionValues, boolean);
- method protected android.animation.Animator play(android.view.ViewGroup, android.view.transition.TransitionValues, android.view.transition.TransitionValues);
}
public abstract class Transition implements java.lang.Cloneable {
@@ -28597,14 +28591,13 @@ package android.view.transition {
method protected void onTransitionCancel();
method protected void onTransitionEnd();
method protected void onTransitionStart();
- method protected abstract android.animation.Animator play(android.view.ViewGroup, android.view.transition.TransitionValues, android.view.transition.TransitionValues);
+ method protected android.animation.Animator play(android.view.ViewGroup, android.view.transition.TransitionValues, android.view.transition.TransitionValues);
method public void removeListener(android.view.transition.Transition.TransitionListener);
method public android.view.transition.Transition setDuration(long);
method public void setInterpolator(android.animation.TimeInterpolator);
method public void setStartDelay(long);
method public android.view.transition.Transition setTargetIds(int...);
method public android.view.transition.Transition setTargets(android.view.View...);
- method protected boolean setup(android.view.ViewGroup, android.view.transition.TransitionValues, android.view.transition.TransitionValues);
}
public static abstract interface Transition.TransitionListener {
@@ -28618,7 +28611,6 @@ package android.view.transition {
ctor public TransitionGroup(int);
method public void addTransitions(android.view.transition.Transition...);
method protected void captureValues(android.view.transition.TransitionValues, boolean);
- method protected android.animation.Animator play(android.view.ViewGroup, android.view.transition.TransitionValues, android.view.transition.TransitionValues);
method public void removeTransition(android.view.transition.Transition);
method public void setOrdering(int);
field public static final int SEQUENTIALLY = 1; // 0x1
@@ -28657,9 +28649,6 @@ package android.view.transition {
method protected android.animation.Animator appear(android.view.ViewGroup, android.view.transition.TransitionValues, int, android.view.transition.TransitionValues, int);
method protected void captureValues(android.view.transition.TransitionValues, boolean);
method protected android.animation.Animator disappear(android.view.ViewGroup, android.view.transition.TransitionValues, int, android.view.transition.TransitionValues, int);
- method protected android.animation.Animator play(android.view.ViewGroup, android.view.transition.TransitionValues, android.view.transition.TransitionValues);
- method protected boolean setupAppear(android.view.ViewGroup, android.view.transition.TransitionValues, int, android.view.transition.TransitionValues, int);
- method protected boolean setupDisappear(android.view.ViewGroup, android.view.transition.TransitionValues, int, android.view.transition.TransitionValues, int);
}
}
diff --git a/core/java/android/view/transition/Crossfade.java b/core/java/android/view/transition/Crossfade.java
index 1e9b6fa56ca8..7cfba7087b2d 100644
--- a/core/java/android/view/transition/Crossfade.java
+++ b/core/java/android/view/transition/Crossfade.java
@@ -140,18 +140,20 @@ public class Crossfade extends Transition {
}
@Override
- protected boolean setup(ViewGroup sceneRoot, TransitionValues startValues,
+ protected Animator play(ViewGroup sceneRoot, TransitionValues startValues,
TransitionValues endValues) {
if (startValues == null || endValues == null) {
- return false;
+ return null;
}
final View view = endValues.view;
Map<String, Object> startVals = startValues.values;
Map<String, Object> endVals = endValues.values;
+ Rect startBounds = (Rect) startVals.get(PROPNAME_BOUNDS);
+ Rect endBounds = (Rect) endVals.get(PROPNAME_BOUNDS);
Bitmap startBitmap = (Bitmap) startVals.get(PROPNAME_BITMAP);
Bitmap endBitmap = (Bitmap) endVals.get(PROPNAME_BITMAP);
- Drawable startDrawable = (Drawable) startVals.get(PROPNAME_DRAWABLE);
- Drawable endDrawable = (Drawable) endVals.get(PROPNAME_DRAWABLE);
+ final BitmapDrawable startDrawable = (BitmapDrawable) startVals.get(PROPNAME_DRAWABLE);
+ final BitmapDrawable endDrawable = (BitmapDrawable) endVals.get(PROPNAME_DRAWABLE);
if (Transition.DBG) {
Log.d(LOG_TAG, "StartBitmap.sameAs(endBitmap) = " + startBitmap.sameAs(endBitmap) +
" for start, end: " + startBitmap + ", " + endBitmap);
@@ -163,80 +165,62 @@ public class Crossfade extends Transition {
overlay.add(endDrawable);
}
overlay.add(startDrawable);
- return true;
- } else {
- return false;
- }
- }
-
- @Override
- protected Animator play(ViewGroup sceneRoot, TransitionValues startValues,
- TransitionValues endValues) {
- if (startValues == null || endValues == null) {
- return null;
- }
- Map<String, Object> startVals = startValues.values;
- Map<String, Object> endVals = endValues.values;
-
- final View view = endValues.view;
- Rect startBounds = (Rect) startVals.get(PROPNAME_BOUNDS);
- Rect endBounds = (Rect) endVals.get(PROPNAME_BOUNDS);
- final BitmapDrawable startDrawable = (BitmapDrawable) startVals.get(PROPNAME_DRAWABLE);
- final BitmapDrawable endDrawable = (BitmapDrawable) endVals.get(PROPNAME_DRAWABLE);
-
- // The transition works by placing the end drawable under the start drawable and
- // gradually fading out the start drawable. So it's not really a cross-fade, but rather
- // a reveal of the end scene over time. Also, animate the bounds of both drawables
- // to mimic the change in the size of the view itself between scenes.
- ObjectAnimator anim = ObjectAnimator.ofInt(startDrawable, "alpha", 0);
- anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
- @Override
- public void onAnimationUpdate(ValueAnimator animation) {
- // TODO: some way to auto-invalidate views based on drawable changes? callbacks?
- view.invalidate(startDrawable.getBounds());
- }
- });
- ObjectAnimator anim1 = null;
- if (mFadeBehavior == FADE_BEHAVIOR_CROSSFADE) {
- anim1 = ObjectAnimator.ofFloat(view, View.ALPHA, 0, 1);
- }
- if (Transition.DBG) {
- Log.d(LOG_TAG, "Crossfade: created anim " + anim + " for start, end values " +
- startValues + ", " + endValues);
- }
- anim.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- ViewOverlay overlay = (mFadeBehavior == FADE_BEHAVIOR_REVEAL) ?
- view.getOverlay() : ((ViewGroup) view.getParent()).getOverlay();
- overlay.remove(startDrawable);
- if (mFadeBehavior == FADE_BEHAVIOR_REVEAL) {
- overlay.remove(endDrawable);
+ // The transition works by placing the end drawable under the start drawable and
+ // gradually fading out the start drawable. So it's not really a cross-fade, but rather
+ // a reveal of the end scene over time. Also, animate the bounds of both drawables
+ // to mimic the change in the size of the view itself between scenes.
+ ObjectAnimator anim = ObjectAnimator.ofInt(startDrawable, "alpha", 0);
+ anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ // TODO: some way to auto-invalidate views based on drawable changes? callbacks?
+ view.invalidate(startDrawable.getBounds());
}
+ });
+ ObjectAnimator anim1 = null;
+ if (mFadeBehavior == FADE_BEHAVIOR_CROSSFADE) {
+ anim1 = ObjectAnimator.ofFloat(view, View.ALPHA, 0, 1);
}
- });
- AnimatorSet set = new AnimatorSet();
- set.playTogether(anim);
- if (anim1 != null) {
- set.playTogether(anim1);
- }
- if (mResizeBehavior == RESIZE_BEHAVIOR_SCALE && !startBounds.equals(endBounds)) {
if (Transition.DBG) {
- Log.d(LOG_TAG, "animating from startBounds to endBounds: " +
- startBounds + ", " + endBounds);
+ Log.d(LOG_TAG, "Crossfade: created anim " + anim + " for start, end values " +
+ startValues + ", " + endValues);
+ }
+ anim.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ ViewOverlay overlay = (mFadeBehavior == FADE_BEHAVIOR_REVEAL) ?
+ view.getOverlay() : ((ViewGroup) view.getParent()).getOverlay();
+ overlay.remove(startDrawable);
+ if (mFadeBehavior == FADE_BEHAVIOR_REVEAL) {
+ overlay.remove(endDrawable);
+ }
+ }
+ });
+ AnimatorSet set = new AnimatorSet();
+ set.playTogether(anim);
+ if (anim1 != null) {
+ set.playTogether(anim1);
}
- Animator anim2 = ObjectAnimator.ofObject(startDrawable, "bounds",
- sRectEvaluator, startBounds, endBounds);
- set.playTogether(anim2);
- if (mResizeBehavior == RESIZE_BEHAVIOR_SCALE) {
- // TODO: How to handle resizing with a CROSSFADE (vs. REVEAL) effect
- // when we are animating the view directly?
- Animator anim3 = ObjectAnimator.ofObject(endDrawable, "bounds",
+ if (mResizeBehavior == RESIZE_BEHAVIOR_SCALE && !startBounds.equals(endBounds)) {
+ if (Transition.DBG) {
+ Log.d(LOG_TAG, "animating from startBounds to endBounds: " +
+ startBounds + ", " + endBounds);
+ }
+ Animator anim2 = ObjectAnimator.ofObject(startDrawable, "bounds",
sRectEvaluator, startBounds, endBounds);
- set.playTogether(anim3);
+ set.playTogether(anim2);
+ if (mResizeBehavior == RESIZE_BEHAVIOR_SCALE) {
+ // TODO: How to handle resizing with a CROSSFADE (vs. REVEAL) effect
+ // when we are animating the view directly?
+ Animator anim3 = ObjectAnimator.ofObject(endDrawable, "bounds",
+ sRectEvaluator, startBounds, endBounds);
+ set.playTogether(anim3);
+ }
}
+ return set;
+ } else {
+ return null;
}
- return set;
}
@Override
diff --git a/core/java/android/view/transition/Fade.java b/core/java/android/view/transition/Fade.java
index f3a4a392a1e9..3c5b6fad622e 100644
--- a/core/java/android/view/transition/Fade.java
+++ b/core/java/android/view/transition/Fade.java
@@ -93,18 +93,6 @@ public class Fade extends Visibility {
}
@Override
- protected boolean setupAppear(ViewGroup sceneRoot,
- TransitionValues startValues, int startVisibility,
- TransitionValues endValues, int endVisibility) {
- View endView = (endValues != null) ? endValues.view : null;
- if ((mFadingMode & IN) != IN) {
- return false;
- }
- endView.setAlpha(0);
- return true;
- }
-
- @Override
protected Animator appear(ViewGroup sceneRoot,
TransitionValues startValues, int startVisibility,
TransitionValues endValues, int endVisibility) {
@@ -112,17 +100,16 @@ public class Fade extends Visibility {
if ((mFadingMode & IN) != IN) {
return null;
}
- // TODO: hack - retain original value from before setupAppear
+ endView.setAlpha(0);
return runAnimation(endView, 0, 1, null);
- // TODO: end listener to make sure we end at 1 no matter what
}
@Override
- protected boolean setupDisappear(ViewGroup sceneRoot,
+ protected Animator disappear(ViewGroup sceneRoot,
TransitionValues startValues, int startVisibility,
TransitionValues endValues, int endVisibility) {
if ((mFadingMode & OUT) != OUT) {
- return false;
+ return null;
}
View view;
View startView = (startValues != null) ? startValues.view : null;
@@ -153,6 +140,7 @@ public class Fade extends Visibility {
}
}
}
+ final int finalVisibility = endVisibility;
// TODO: add automatic facility to Visibility superclass for keeping views around
if (overlayView != null) {
// TODO: Need to do this for general case of adding to overlay
@@ -163,75 +151,55 @@ public class Fade extends Visibility {
overlayView.offsetLeftAndRight((screenX - loc[0]) - overlayView.getLeft());
overlayView.offsetTopAndBottom((screenY - loc[1]) - overlayView.getTop());
sceneRoot.getOverlay().add(overlayView);
- return true;
+ // TODO: add automatic facility to Visibility superclass for keeping views around
+ final float startAlpha = view.getAlpha();
+ float endAlpha = 0;
+ final View finalView = view;
+ final View finalOverlayView = overlayView;
+ final View finalViewToKeep = viewToKeep;
+ final ViewGroup finalSceneRoot = sceneRoot;
+ final Animator.AnimatorListener endListener = new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ finalView.setAlpha(startAlpha);
+ // TODO: restore view offset from overlay repositioning
+ if (finalViewToKeep != null) {
+ finalViewToKeep.setVisibility(finalVisibility);
+ }
+ if (finalOverlayView != null) {
+ finalSceneRoot.getOverlay().remove(finalOverlayView);
+ }
+ }
+ };
+ return runAnimation(view, startAlpha, endAlpha, endListener);
}
if (viewToKeep != null) {
// TODO: find a different way to do this, like just changing the view to be
// VISIBLE for the duration of the transition
viewToKeep.setVisibility((View.VISIBLE));
- return true;
- }
- return false;
- }
-
- @Override
- protected Animator disappear(ViewGroup sceneRoot,
- TransitionValues startValues, int startVisibility,
- TransitionValues endValues, int endVisibility) {
- if ((mFadingMode & OUT) != OUT) {
- return null;
- }
- View startView = (startValues != null) ? startValues.view : null;
- View endView = (endValues != null) ? endValues.view : null;
- if (Transition.DBG) {
- Log.d(LOG_TAG, "Fade.disappear: startView, startVis, endView, endVis = " +
- startView + ", " + startVisibility + ", " + endView + ", " + endVisibility);
- }
- View view;
- View overlayView = null;
- View viewToKeep = null;
- final int finalVisibility = endVisibility;
- if (endView == null) {
- // view was removed: add the start view to the Overlay
- view = startView;
- overlayView = view;
- } else {
- // visibility change
- if (endVisibility == View.INVISIBLE) {
- view = endView;
- viewToKeep = view;
- } else {
- // Becoming GONE
- if (startView == endView) {
- view = endView;
- viewToKeep = view;
- } else {
- view = startView;
- overlayView = view;
+ // TODO: add automatic facility to Visibility superclass for keeping views around
+ final float startAlpha = view.getAlpha();
+ float endAlpha = 0;
+ final View finalView = view;
+ final View finalOverlayView = overlayView;
+ final View finalViewToKeep = viewToKeep;
+ final ViewGroup finalSceneRoot = sceneRoot;
+ final Animator.AnimatorListener endListener = new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ finalView.setAlpha(startAlpha);
+ // TODO: restore view offset from overlay repositioning
+ if (finalViewToKeep != null) {
+ finalViewToKeep.setVisibility(finalVisibility);
+ }
+ if (finalOverlayView != null) {
+ finalSceneRoot.getOverlay().remove(finalOverlayView);
+ }
}
- }
+ };
+ return runAnimation(view, startAlpha, endAlpha, endListener);
}
- // TODO: add automatic facility to Visibility superclass for keeping views around
- final float startAlpha = view.getAlpha();
- float endAlpha = 0;
- final View finalView = view;
- final View finalOverlayView = overlayView;
- final View finalViewToKeep = viewToKeep;
- final ViewGroup finalSceneRoot = sceneRoot;
- final Animator.AnimatorListener endListener = new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- finalView.setAlpha(startAlpha);
- // TODO: restore view offset from overlay repositioning
- if (finalViewToKeep != null) {
- finalViewToKeep.setVisibility(finalVisibility);
- }
- if (finalOverlayView != null) {
- finalSceneRoot.getOverlay().remove(finalOverlayView);
- }
- }
- };
- return runAnimation(view, startAlpha, endAlpha, endListener);
+ return null;
}
} \ No newline at end of file
diff --git a/core/java/android/view/transition/Move.java b/core/java/android/view/transition/Move.java
index 5c9da887819a..ceda5a5f6f6e 100644
--- a/core/java/android/view/transition/Move.java
+++ b/core/java/android/view/transition/Move.java
@@ -84,24 +84,21 @@ public class Move extends Transition {
if (startValues == null || endValues == null) {
return null;
}
- final View view = endValues.view;
- if (view.getParent() == null) {
- // TODO: Might want to make it possible to Move an disappearing view.
- // This workaround is here because if a parallel Fade is not running on the view
- // Then it won't get added to the hierarchy and the animator below will not fire,
- // causing the transition to not end
- return null;
- }
- // TODO: need to handle non-VG case?
- ViewGroup startParent = (ViewGroup) startValues.values.get(PROPNAME_PARENT);
- ViewGroup endParent = (ViewGroup) endValues.values.get(PROPNAME_PARENT);
+ Map<String, Object> startParentVals = startValues.values;
+ Map<String, Object> endParentVals = endValues.values;
+ ViewGroup startParent = (ViewGroup) startParentVals.get(PROPNAME_PARENT);
+ ViewGroup endParent = (ViewGroup) endParentVals.get(PROPNAME_PARENT);
if (startParent == null || endParent == null) {
return null;
}
+ final View view = endValues.view;
boolean parentsEqual = (startParent == endParent) ||
(startParent.getId() == endParent.getId());
+ // TODO: Might want reparenting to be separate/subclass transition, or at least
+ // triggered by a property on Move. Otherwise, we're forcing the requirement that
+ // all parents in layouts have IDs to avoid layout-inflation resulting in a side-effect
+ // of reparenting the views.
if (!mReparent || parentsEqual) {
- // Common case - view belongs to the same layout before/after. Just animate its bounds
Rect startBounds = (Rect) startValues.values.get(PROPNAME_BOUNDS);
Rect endBounds = (Rect) endValues.values.get(PROPNAME_BOUNDS);
int startLeft = startBounds.left;
@@ -118,13 +115,6 @@ public class Move extends Transition {
int endHeight = endBottom - endTop;
int numChanges = 0;
if (startWidth != 0 && startHeight != 0 && endWidth != 0 && endHeight != 0) {
- if (Transition.DBG) {
- Log.v(LOG_TAG, "Target = " + endValues.view);
- Log.v(LOG_TAG, " start bounds: " + startLeft + ", " + startTop + ", " +
- startRight + ", " + startBottom);
- Log.v(LOG_TAG, " end bounds: " + endLeft + ", " + endTop + ", " +
- endRight + ", " + endBottom);
- }
if (startLeft != endLeft) ++numChanges;
if (startTop != endTop) ++numChanges;
if (startRight != endRight) ++numChanges;
@@ -134,6 +124,10 @@ public class Move extends Transition {
if (!mResizeClip) {
PropertyValuesHolder pvh[] = new PropertyValuesHolder[numChanges];
int pvhIndex = 0;
+ if (startLeft != endLeft) view.setLeft(startLeft);
+ if (startTop != endTop) view.setTop(startTop);
+ if (startRight != endRight) view.setRight(startRight);
+ if (startBottom != endBottom) view.setBottom(startBottom);
if (startLeft != endLeft) {
pvh[pvhIndex++] = PropertyValuesHolder.ofInt("left", startLeft, endLeft);
}
@@ -161,6 +155,13 @@ public class Move extends Transition {
}
return anim;
} else {
+ if (startWidth != endWidth) view.setRight(endLeft +
+ Math.max(startWidth, endWidth));
+ if (startHeight != endHeight) view.setBottom(endTop +
+ Math.max(startHeight, endHeight));
+ // TODO: don't clobber TX/TY
+ if (startLeft != endLeft) view.setTranslationX(startLeft - endLeft);
+ if (startTop != endTop) view.setTranslationY(startTop - endTop);
// Animate location with translationX/Y and size with clip bounds
float transXDelta = endLeft - startLeft;
float transYDelta = endTop - startTop;
@@ -207,71 +208,6 @@ public class Move extends Transition {
}
}
} else {
- return (ObjectAnimator) endValues.values.get("drawableAnim");
- }
- return null;
- }
-
- @Override
- protected boolean setup(final ViewGroup sceneRoot, TransitionValues startValues,
- TransitionValues endValues) {
- if (startValues == null || endValues == null) {
- return false;
- }
- Map<String, Object> startParentVals = startValues.values;
- Map<String, Object> endParentVals = endValues.values;
- ViewGroup startParent = (ViewGroup) startParentVals.get(PROPNAME_PARENT);
- ViewGroup endParent = (ViewGroup) endParentVals.get(PROPNAME_PARENT);
- if (startParent == null || endParent == null) {
- return false;
- }
- final View view = endValues.view;
- boolean parentsEqual = (startParent == endParent) ||
- (startParent.getId() == endParent.getId());
- // TODO: Might want reparenting to be separate/subclass transition, or at least
- // triggered by a property on Move. Otherwise, we're forcing the requirement that
- // all parents in layouts have IDs to avoid layout-inflation resulting in a side-effect
- // of reparenting the views.
- if (!mReparent || parentsEqual) {
- Rect startBounds = (Rect) startValues.values.get(PROPNAME_BOUNDS);
- Rect endBounds = (Rect) endValues.values.get(PROPNAME_BOUNDS);
- int startLeft = startBounds.left;
- int endLeft = endBounds.left;
- int startTop = startBounds.top;
- int endTop = endBounds.top;
- int startRight = startBounds.right;
- int endRight = endBounds.right;
- int startBottom = startBounds.bottom;
- int endBottom = endBounds.bottom;
- int startWidth = startRight - startLeft;
- int startHeight = startBottom - startTop;
- int endWidth = endRight - endLeft;
- int endHeight = endBottom - endTop;
- int numChanges = 0;
- if (startWidth != 0 && startHeight != 0 && endWidth != 0 && endHeight != 0) {
- if (startLeft != endLeft) ++numChanges;
- if (startTop != endTop) ++numChanges;
- if (startRight != endRight) ++numChanges;
- if (startBottom != endBottom) ++numChanges;
- }
- if (numChanges > 0) {
- if (!mResizeClip) {
- if (startLeft != endLeft) view.setLeft(startLeft);
- if (startTop != endTop) view.setTop(startTop);
- if (startRight != endRight) view.setRight(startRight);
- if (startBottom != endBottom) view.setBottom(startBottom);
- } else {
- if (startWidth != endWidth) view.setRight(endLeft +
- Math.max(startWidth, endWidth));
- if (startHeight != endHeight) view.setBottom(endTop +
- Math.max(startHeight, endHeight));
- // TODO: don't clobber TX/TY
- if (startLeft != endLeft) view.setTranslationX(startLeft - endLeft);
- if (startTop != endTop) view.setTranslationY(startTop - endTop);
- }
- return true;
- }
- } else {
int startX = (Integer) startValues.values.get(PROPNAME_WINDOW_X);
int startY = (Integer) startValues.values.get(PROPNAME_WINDOW_Y);
int endX = (Integer) endValues.values.get(PROPNAME_WINDOW_X);
@@ -286,14 +222,14 @@ public class Move extends Transition {
final BitmapDrawable drawable = new BitmapDrawable(bitmap);
view.setVisibility(View.INVISIBLE);
sceneRoot.getOverlay().add(drawable);
- Rect startBounds = new Rect(startX - tempLocation[0], startY - tempLocation[1],
+ Rect startBounds1 = new Rect(startX - tempLocation[0], startY - tempLocation[1],
startX - tempLocation[0] + view.getWidth(),
startY - tempLocation[1] + view.getHeight());
- Rect endBounds = new Rect(endX - tempLocation[0], endY - tempLocation[1],
+ Rect endBounds1 = new Rect(endX - tempLocation[0], endY - tempLocation[1],
endX - tempLocation[0] + view.getWidth(),
endY - tempLocation[1] + view.getHeight());
ObjectAnimator anim = ObjectAnimator.ofObject(drawable, "bounds",
- sRectEvaluator, startBounds, endBounds);
+ sRectEvaluator, startBounds1, endBounds1);
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
@@ -301,10 +237,9 @@ public class Move extends Transition {
view.setVisibility(View.VISIBLE);
}
});
- endParentVals.put("drawableAnim", anim);
- return true;
+ return anim;
}
}
- return false;
+ return null;
}
}
diff --git a/core/java/android/view/transition/Recolor.java b/core/java/android/view/transition/Recolor.java
index 217996059ad1..e4858c4d0a11 100644
--- a/core/java/android/view/transition/Recolor.java
+++ b/core/java/android/view/transition/Recolor.java
@@ -51,10 +51,10 @@ public class Recolor extends Transition {
}
@Override
- protected boolean setup(ViewGroup sceneRoot, TransitionValues startValues,
+ protected Animator play(ViewGroup sceneRoot, TransitionValues startValues,
TransitionValues endValues) {
if (startValues == null || endValues == null) {
- return false;
+ return null;
}
final View view = endValues.view;
Drawable startBackground = (Drawable) startValues.values.get(PROPNAME_BACKGROUND);
@@ -66,6 +66,8 @@ public class Recolor extends Transition {
if (startColor.getColor() != endColor.getColor()) {
endColor.setColor(startColor.getColor());
changed = true;
+ return ObjectAnimator.ofObject(endBackground, "color",
+ new ArgbEvaluator(), startColor.getColor(), endColor.getColor());
}
}
if (view instanceof TextView) {
@@ -75,46 +77,10 @@ public class Recolor extends Transition {
if (start != end) {
textView.setTextColor(end);
changed = true;
- }
- }
- return changed;
- }
-
- @Override
- protected Animator play(ViewGroup sceneRoot, TransitionValues startValues,
- TransitionValues endValues) {
- if (startValues == null || endValues == null) {
- return null;
- }
- ObjectAnimator anim = null;
- final View view = endValues.view;
- Map<String, Object> startVals = startValues.values;
- Map<String, Object> endVals = endValues.values;
- Drawable startBackground = (Drawable) startVals.get(PROPNAME_BACKGROUND);
- Drawable endBackground = (Drawable) endVals.get(PROPNAME_BACKGROUND);
- if (startBackground instanceof ColorDrawable && endBackground instanceof ColorDrawable) {
- ColorDrawable startColor = (ColorDrawable) startBackground;
- ColorDrawable endColor = (ColorDrawable) endBackground;
- if (startColor.getColor() != endColor.getColor()) {
- anim = ObjectAnimator.ofObject(endBackground, "color",
- new ArgbEvaluator(), startColor.getColor(), endColor.getColor());
- if (getStartDelay() > 0) {
- endColor.setColor(startColor.getColor());
- }
- }
- }
- if (view instanceof TextView) {
- TextView textView = (TextView) view;
- int start = (Integer) startValues.values.get(PROPNAME_TEXT_COLOR);
- int end = (Integer) endValues.values.get(PROPNAME_TEXT_COLOR);
- if (start != end) {
- anim = ObjectAnimator.ofObject(textView, "textColor",
+ return ObjectAnimator.ofObject(textView, "textColor",
new ArgbEvaluator(), start, end);
- if (getStartDelay() > 0) {
- textView.setTextColor(end);
- }
}
}
- return anim;
+ return null;
}
}
diff --git a/core/java/android/view/transition/Rotate.java b/core/java/android/view/transition/Rotate.java
index 8d579d2b8cdf..d35a6dc745e5 100644
--- a/core/java/android/view/transition/Rotate.java
+++ b/core/java/android/view/transition/Rotate.java
@@ -35,22 +35,6 @@ public class Rotate extends Transition {
}
@Override
- protected boolean setup(ViewGroup sceneRoot, TransitionValues startValues,
- TransitionValues endValues) {
- if (startValues == null || endValues == null) {
- return false;
- }
- final View view = endValues.view;
- float startRotation = (Float) startValues.values.get(PROPNAME_ROTATION);
- float endRotation = (Float) endValues.values.get(PROPNAME_ROTATION);
- if (startRotation != endRotation) {
- view.setRotation(startRotation);
- return true;
- }
- return false;
- }
-
- @Override
protected Animator play(ViewGroup sceneRoot, TransitionValues startValues,
TransitionValues endValues) {
if (startValues == null || endValues == null) {
@@ -60,6 +44,7 @@ public class Rotate extends Transition {
float startRotation = (Float) startValues.values.get(PROPNAME_ROTATION);
float endRotation = (Float) endValues.values.get(PROPNAME_ROTATION);
if (startRotation != endRotation) {
+ view.setRotation(startRotation);
return ObjectAnimator.ofFloat(view, View.ROTATION,
startRotation, endRotation);
}
diff --git a/core/java/android/view/transition/Slide.java b/core/java/android/view/transition/Slide.java
index e39daa6c0806..b2f5db5ea522 100644
--- a/core/java/android/view/transition/Slide.java
+++ b/core/java/android/view/transition/Slide.java
@@ -41,6 +41,7 @@ public class Slide extends Visibility {
TransitionValues startValues, int startVisibility,
TransitionValues endValues, int endVisibility) {
View endView = (endValues != null) ? endValues.view : null;
+ endView.setTranslationY(-2 * endView.getHeight());
ObjectAnimator anim = ObjectAnimator.ofFloat(endView, View.TRANSLATION_Y,
-2 * endView.getHeight(), 0);
anim.setInterpolator(sDecelerator);
@@ -48,28 +49,11 @@ public class Slide extends Visibility {
}
@Override
- protected boolean setupAppear(ViewGroup sceneRoot,
- TransitionValues startValues, int startVisibility,
- TransitionValues endValues, int endVisibility) {
- View endView = (endValues != null) ? endValues.view : null;
- endView.setTranslationY(-2 * endView.getHeight());
- return true;
- }
-
- @Override
- protected boolean setupDisappear(ViewGroup sceneRoot,
- TransitionValues startValues, int startVisibility,
- TransitionValues endValues, int endVisibility) {
- View startView = (startValues != null) ? startValues.view : null;
- startView.setTranslationY(0);
- return true;
- }
-
- @Override
protected Animator disappear(ViewGroup sceneRoot,
TransitionValues startValues, int startVisibility,
TransitionValues endValues, int endVisibility) {
View startView = (startValues != null) ? startValues.view : null;
+ startView.setTranslationY(0);
ObjectAnimator anim = ObjectAnimator.ofFloat(startView, View.TRANSLATION_Y, 0,
-2 * startView.getHeight());
anim.setInterpolator(sAccelerator);
diff --git a/core/java/android/view/transition/TextChange.java b/core/java/android/view/transition/TextChange.java
index 16e990fd58b4..f033e633b30c 100644
--- a/core/java/android/view/transition/TextChange.java
+++ b/core/java/android/view/transition/TextChange.java
@@ -47,24 +47,6 @@ public class TextChange extends Transition {
}
@Override
- protected boolean setup(ViewGroup sceneRoot, TransitionValues startValues,
- TransitionValues endValues) {
- if (startValues == null || endValues == null || !(endValues.view instanceof TextView)) {
- return false;
- }
- final TextView view = (TextView) endValues.view;
- Map<String, Object> startVals = startValues.values;
- Map<String, Object> endVals = endValues.values;
- String startText = (String) startVals.get(PROPNAME_TEXT);
- String endText = (String) endVals.get(PROPNAME_TEXT);
- if (!startText.equals(endText)) {
- view.setText(startText);
- return true;
- }
- return false;
- }
-
- @Override
protected Animator play(ViewGroup sceneRoot, TransitionValues startValues,
TransitionValues endValues) {
if (startValues == null || endValues == null || !(endValues.view instanceof TextView)) {
@@ -73,11 +55,10 @@ public class TextChange extends Transition {
final TextView view = (TextView) endValues.view;
Map<String, Object> startVals = startValues.values;
Map<String, Object> endVals = endValues.values;
- final String startText = (String) startVals.get(PROPNAME_TEXT);
+ String startText = (String) startVals.get(PROPNAME_TEXT);
final String endText = (String) endVals.get(PROPNAME_TEXT);
if (!startText.equals(endText)) {
- // This noop animation is just used to keep the text in its start state
- // until the transition ends
+ view.setText(startText);
ValueAnimator anim = ValueAnimator.ofFloat(0, 1);
anim.addListener(new AnimatorListenerAdapter() {
@Override
diff --git a/core/java/android/view/transition/Transition.java b/core/java/android/view/transition/Transition.java
index fd12339485c9..2cffd268940a 100644
--- a/core/java/android/view/transition/Transition.java
+++ b/core/java/android/view/transition/Transition.java
@@ -21,6 +21,7 @@ import android.animation.AnimatorListenerAdapter;
import android.animation.TimeInterpolator;
import android.util.ArrayMap;
import android.util.LongSparseArray;
+import android.util.Pair;
import android.util.SparseArray;
import android.view.SurfaceView;
import android.view.TextureView;
@@ -149,49 +150,32 @@ public abstract class Transition implements Cloneable {
/**
* This method is called by the transition's parent (all the way up to the
* topmost Transition in the hierarchy) with the sceneRoot and start/end
- * values that the transition may need to run animations on its target
- * views. The method is called for every applicable target object, which
- * is stored in the {@link TransitionValues#view} field. When the method
- * results in an animation needing to be run, the transition will construct
- * the appropriate {@link Animator} object and return it. The transition
- * mechanism will apply any applicable duration, startDelay, and interpolator
- * to that animation and start it. Returning null from the method tells the
- * transition engine that there is no animation to be played (TransitionGroup
- * will return null because any applicable animations were started on its child
- * transitions already and there is no animation to be run on the group itself).
- *
- * @param sceneRoot
- * @param startValues
- * @param endValues
- * @return Animator The animation to run.
- */
- protected abstract Animator play(ViewGroup sceneRoot, TransitionValues startValues,
- TransitionValues endValues);
-
- /**
- * This method is called by the transition's parent (all the way up to the
- * topmost Transition in the hierarchy) with the sceneRoot and start/end
- * values that the transition may need to set things up at the start of a
- * Transition. For example, if an overall Transition consists of several
+ * values that the transition may need to set up initial target values
+ * and construct an appropriate animation. For example, if an overall
+ * Transition is a {@link TransitionGroup} consisting of several
* child transitions in sequence, then some of the child transitions may
* want to set initial values on target views prior to the overall
- * Transition commencing, to put them in an appropriate scene for the
+ * Transition commencing, to put them in an appropriate state for the
* delay between that start and the child Transition start time. For
* example, a transition that fades an item in may wish to set the starting
* alpha value to 0, to avoid it blinking in prior to the transition
* actually starting the animation. This is necessary because the scene
* change that triggers the Transition will automatically set the end-scene
* on all target views, so a Transition that wants to animate from a
- * different value should set that value in the setup() method.
+ * different value should set that value prior to returning from this method.
*
* <p>Additionally, a Transition can perform logic to determine whether
* the transition needs to run on the given target and start/end values.
* For example, a transition that resizes objects on the screen may wish
* to avoid running for views which are not present in either the start
- * or end scenes. A return value of <code>false</code> indicates that
- * the transition should not run, and there will be no ensuing call to the
- * {@link #play(ViewGroup, TransitionValues, TransitionValues)} method during
- * this scene change. The default implementation returns true.</p>
+ * or end scenes. A return value of <code>null</code> indicates that
+ * no animation should run. The default implementation returns null.</p>
+ *
+ * <p>If there is an animator created and returned from this method, the
+ * transition mechanism will apply any applicable duration, startDelay,
+ * and interpolator to that animation and start it. A return value of
+ * <code>null</code> indicates that no animation should run. The default
+ * implementation returns null.</p>
*
* <p>The method is called for every applicable target object, which is
* stored in the {@link TransitionValues#view} field.</p>
@@ -199,31 +183,25 @@ public abstract class Transition implements Cloneable {
* @param sceneRoot
* @param startValues
* @param endValues
- * @return True if the Transition's {@link #play(ViewGroup,
- * TransitionValues, TransitionValues) play()} method should be called
- * during this scene change, false otherwise.
+ * @return A non-null Animator to be started at the appropriate time in the
+ * overall transition for this scene change, null otherwise.
*/
- protected boolean setup(ViewGroup sceneRoot, TransitionValues startValues,
+ protected Animator play(ViewGroup sceneRoot, TransitionValues startValues,
TransitionValues endValues) {
- return true;
+ return null;
}
/**
- * This version of setup() is called with the entire set of start/end
+ * This version of play() is called with the entire set of start/end
* values. The implementation in Transition iterates through these lists
- * and calls {@link #setup(ViewGroup, TransitionValues, TransitionValues)}
+ * and calls {@link #play(ViewGroup, TransitionValues, TransitionValues)}
* with each set of start/end values on this transition. The
* TransitionGroup subclass overrides this method and delegates it to
- * each of its children in succession. The intention in splitting
- * setup() out from play() is to allow all Transitions in the tree to
- * set up the appropriate start scene for their target objects prior to
- * any calls to play(), which is necessary when there is a sequential
- * Transition, where a child transition which is not the first may want to
- * set up a target's scene prior to the overall Transition start.
+ * each of its children in succession.
*
* @hide
*/
- protected void setup(ViewGroup sceneRoot, TransitionValuesMaps startValues,
+ protected void play(ViewGroup sceneRoot, TransitionValuesMaps startValues,
TransitionValuesMaps endValues) {
mPlayStartValuesList.clear();
mPlayEndValuesList.clear();
@@ -335,7 +313,9 @@ public abstract class Transition implements Cloneable {
TransitionValues start = startValuesList.get(i);
TransitionValues end = endValuesList.get(i);
// TODO: what to do about targetIds and itemIds?
- if (setup(sceneRoot, start, end)) {
+ Animator animator = play(sceneRoot, start, end);
+ if (animator != null) {
+ mAnimatorMap.put(new Pair(start, end), animator);
// Note: we've already done the check against targetIDs in these lists
mPlayStartValuesList.add(start);
mPlayEndValuesList.add(end);
@@ -343,6 +323,9 @@ public abstract class Transition implements Cloneable {
}
}
+ ArrayMap<Pair<TransitionValues, TransitionValues>, Animator> mAnimatorMap =
+ new ArrayMap<Pair<TransitionValues, TransitionValues>, Animator>();
+
/**
* Internal utility method for checking whether a given view/id
* is valid for this transition, where "valid" means that either
@@ -375,16 +358,12 @@ public abstract class Transition implements Cloneable {
}
/**
- * This version of play() is called with the entire set of start/end
- * values. The implementation in Transition iterates through these lists
- * and calls {@link #play(ViewGroup, TransitionValues, TransitionValues)}
- * with each set of start/end values on this transition. The
- * TransitionGroup subclass overrides this method and delegates it to
- * each of its children in succession.
+ * This is called internally once all animations have been set up by the
+ * transition hierarchy. \
*
* @hide
*/
- protected void play(ViewGroup sceneRoot) {
+ protected void runAnimations() {
startTransition();
// Now walk the list of TransitionValues, calling play for each pair
@@ -392,10 +371,11 @@ public abstract class Transition implements Cloneable {
TransitionValues start = mPlayStartValuesList.get(i);
TransitionValues end = mPlayEndValuesList.get(i);
startTransition();
- runAnimator(play(sceneRoot, start, end));
+ runAnimator(mAnimatorMap.get(new Pair(start, end)));
}
mPlayStartValuesList.clear();
mPlayEndValuesList.clear();
+ mAnimatorMap.clear();
endTransition();
}
@@ -424,19 +404,18 @@ public abstract class Transition implements Cloneable {
* <code>start</code>. The main concern for an implementation is what the
* properties are that the transition cares about and what the values are
* for all of those properties. The start and end values will be compared
- * later during the setup() and play() methods to determine what, if any,
- * animations, should be run.
+ * later during the
+ * {@link #play(android.view.ViewGroup, TransitionValues, TransitionValues)}
+ * method to determine what, if any, animations, should be run.
*
- * @param transitionValues The holder any values that the Transition
- * wishes to store. Values are stored in the fields of this
- * TransitionValues object, according to their type, and are keyed from
- * a String value. For example, to start a view's rotation value,
- * a Transition might call
- * <code>transitionValues.floatValues.put("rotation", view.getRotation())
- * </code>. The target <code>View</code> will already be stored in
- * the transitionValues structure when this method is called. The other
- * fields in TransitionValues, e.g. <code>floatValues</code>,
- * may need to be instantiated if they have not yet been created.
+ * @param transitionValues The holder for any values that the Transition
+ * wishes to store. Values are stored in the <code>values</code> field
+ * of this TransitionValues object and are keyed from
+ * a String value. For example, to store a view's rotation value,
+ * a transition might call
+ * <code>transitionValues.values.put("appname:transitionname:rotation",
+ * view.getRotation())</code>. The target view will already be stored in
+ * the transitionValues structure when this method is called.
*/
protected abstract void captureValues(TransitionValues transitionValues, boolean start);
@@ -666,15 +645,15 @@ public abstract class Transition implements Cloneable {
/**
* Called by TransitionManager to play the transition. This calls
- * setup() and then play() with the full set of per-view
- * transitionValues objects
+ * play() to set things up and create all of the animations and then
+ * runAnimations() to actually start the animations.
*/
void playTransition(ViewGroup sceneRoot) {
// setup() must be called on entire transition hierarchy and set of views
// before calling play() on anything; every transition needs a chance to set up
// target views appropriately before transitions begin running
- setup(sceneRoot, mStartValues, mEndValues);
- play(sceneRoot);
+ play(sceneRoot, mStartValues, mEndValues);
+ runAnimations();
}
/**
diff --git a/core/java/android/view/transition/TransitionGroup.java b/core/java/android/view/transition/TransitionGroup.java
index 6f9a3ef06dfb..d0e61ea28c4b 100644
--- a/core/java/android/view/transition/TransitionGroup.java
+++ b/core/java/android/view/transition/TransitionGroup.java
@@ -16,9 +16,7 @@
package android.view.transition;
-import android.animation.Animator;
import android.util.AndroidRuntimeException;
-import android.view.View;
import android.view.ViewGroup;
import java.util.ArrayList;
@@ -187,10 +185,10 @@ public class TransitionGroup extends Transition {
* @hide
*/
@Override
- protected void setup(ViewGroup sceneRoot, TransitionValuesMaps startValues,
+ protected void play(ViewGroup sceneRoot, TransitionValuesMaps startValues,
TransitionValuesMaps endValues) {
for (Transition childTransition : mTransitions) {
- childTransition.setup(sceneRoot, startValues, endValues);
+ childTransition.play(sceneRoot, startValues, endValues);
}
}
@@ -198,9 +196,8 @@ public class TransitionGroup extends Transition {
* @hide
*/
@Override
- protected void play(ViewGroup sceneRoot) {
+ protected void runAnimations() {
setupStartEndListeners();
- final ViewGroup finalSceneRoot = sceneRoot;
if (!mPlayTogether) {
// Setup sequence with listeners
// TODO: Need to add listeners in such a way that we can remove them later if canceled
@@ -210,78 +207,23 @@ public class TransitionGroup extends Transition {
previousTransition.addListener(new TransitionListenerAdapter() {
@Override
public void onTransitionEnd(Transition transition) {
- nextTransition.play(finalSceneRoot);
+ nextTransition.runAnimations();
transition.removeListener(this);
}
});
}
Transition firstTransition = mTransitions.get(0);
if (firstTransition != null) {
- firstTransition.play(finalSceneRoot);
+ firstTransition.runAnimations();
}
} else {
for (Transition childTransition : mTransitions) {
- childTransition.play(finalSceneRoot);
+ childTransition.runAnimations();
}
}
}
@Override
- protected Animator play(ViewGroup sceneRoot,
- TransitionValues startValues, TransitionValues endValues) {
- final View view = (endValues != null) ? endValues.view :
- (startValues != null) ? startValues.view : null;
- final int targetId = (view != null) ? view.getId() : -1;
- // TODO: not sure this is a valid check - what about auto-targets? No need for ids.
- if (targetId < 0) {
- return null;
- }
- setupStartEndListeners();
- if (!mPlayTogether) {
- final ViewGroup finalSceneRoot = sceneRoot;
- final TransitionValues finalStartValues = startValues;
- final TransitionValues finalEndValues = endValues;
- // Setup sequence with listeners
- // TODO: Need to add listeners in such a way that we can remove them later if canceled
- for (int i = 1; i < mTransitions.size(); ++i) {
- Transition previousTransition = mTransitions.get(i - 1);
- final Transition nextTransition = mTransitions.get(i);
- previousTransition.addListener(new TransitionListenerAdapter() {
- @Override
- public void onTransitionEnd(Transition transition) {
- nextTransition.startTransition();
- if (nextTransition.isValidTarget(view, targetId)) {
- animate(nextTransition.play(finalSceneRoot, finalStartValues,
- finalEndValues));
- } else {
- nextTransition.endTransition();
- }
- }
- });
- }
- Transition firstTransition = mTransitions.get(0);
- if (firstTransition != null) {
- firstTransition.startTransition();
- if (firstTransition.isValidTarget(view, targetId)) {
- animate(firstTransition.play(finalSceneRoot, finalStartValues, finalEndValues));
- } else {
- firstTransition.endTransition();
- }
- }
- } else {
- for (Transition childTransition : mTransitions) {
- childTransition.startTransition();
- if (childTransition.isValidTarget(view, targetId)) {
- animate(childTransition.play(sceneRoot, startValues, endValues));
- } else {
- childTransition.endTransition();
- }
- }
- }
- return null;
- }
-
- @Override
protected void captureValues(TransitionValues transitionValues, boolean start) {
int targetId = transitionValues.view.getId();
for (Transition childTransition : mTransitions) {
diff --git a/core/java/android/view/transition/TransitionValues.java b/core/java/android/view/transition/TransitionValues.java
index 963e04dac1e8..f36166655df6 100644
--- a/core/java/android/view/transition/TransitionValues.java
+++ b/core/java/android/view/transition/TransitionValues.java
@@ -36,9 +36,9 @@ import java.util.Map;
* {@link Transition#captureValues(TransitionValues, boolean)}
* capture} phases of a scene change, once when the start values are captured
* and again when the end values are captured. These start/end values are then
- * passed into the transitions during the play phase of the scene change,
- * for {@link Transition#setup(ViewGroup, TransitionValues, TransitionValues)} and
- * for {@link Transition#play(ViewGroup, TransitionValues, TransitionValues)}.</p>
+ * passed into the transitions via the
+ * for {@link Transition#play(ViewGroup, TransitionValues, TransitionValues)}
+ * method.</p>
*/
public class TransitionValues {
diff --git a/core/java/android/view/transition/Visibility.java b/core/java/android/view/transition/Visibility.java
index c9dba6bfff19..6d39ab650d28 100644
--- a/core/java/android/view/transition/Visibility.java
+++ b/core/java/android/view/transition/Visibility.java
@@ -29,8 +29,8 @@ import android.view.ViewParent;
* utility for subclasses such as {@link Fade}, which use this visibility
* information to determine the specific animations to run when visibility
* changes occur. Subclasses should implement one or more of the methods
- * {@link #setupAppear(ViewGroup, TransitionValues, int, TransitionValues, int)},
- * {@link #setupDisappear(ViewGroup, TransitionValues, int, TransitionValues, int)},
+ * {@link #appear(ViewGroup, TransitionValues, int, TransitionValues, int)},
+ * {@link #disappear(ViewGroup, TransitionValues, int, TransitionValues, int)},
* {@link #appear(ViewGroup, TransitionValues, int, TransitionValues, int)}, and
* {@link #disappear(ViewGroup, TransitionValues, int, TransitionValues, int)}.
*/
@@ -139,7 +139,7 @@ public abstract class Visibility extends Transition {
}
@Override
- protected boolean setup(ViewGroup sceneRoot, TransitionValues startValues,
+ protected Animator play(ViewGroup sceneRoot, TransitionValues startValues,
TransitionValues endValues) {
VisibilityInfo visInfo = getVisibilityChangeInfo(startValues, endValues);
// Ensure not in parent hierarchy that's also becoming visible/invisible
@@ -149,32 +149,16 @@ public abstract class Visibility extends Transition {
if (parent != null) {
if (!isHierarchyVisibilityChanging(sceneRoot, parent)) {
if (visInfo.fadeIn) {
- return setupAppear(sceneRoot, startValues, visInfo.startVisibility,
+ return appear(sceneRoot, startValues, visInfo.startVisibility,
endValues, visInfo.endVisibility);
} else {
- return setupDisappear(sceneRoot, startValues, visInfo.startVisibility,
+ return disappear(sceneRoot, startValues, visInfo.startVisibility,
endValues, visInfo.endVisibility
);
}
}
}
}
- return false;
- }
-
- @Override
- protected Animator play(ViewGroup sceneRoot, TransitionValues startValues,
- TransitionValues endValues) {
- VisibilityInfo visInfo = getVisibilityChangeInfo(startValues, endValues);
- if (visInfo.visibilityChange) {
- if (visInfo.fadeIn) {
- return appear(sceneRoot, startValues, visInfo.startVisibility,
- endValues, visInfo.endVisibility);
- } else {
- return disappear(sceneRoot, startValues, visInfo.startVisibility,
- endValues, visInfo.endVisibility);
- }
- }
return null;
}
@@ -190,10 +174,10 @@ public abstract class Visibility extends Transition {
* @param endVisibility
* @return
*/
- protected boolean setupAppear(ViewGroup sceneRoot,
+ protected Animator appear(ViewGroup sceneRoot,
TransitionValues startValues, int startVisibility,
TransitionValues endValues, int endVisibility) {
- return true;
+ return null;
}
/**
@@ -208,38 +192,6 @@ public abstract class Visibility extends Transition {
* @param endVisibility
* @return
*/
- protected boolean setupDisappear(ViewGroup sceneRoot,
- TransitionValues startValues, int startVisibility,
- TransitionValues endValues, int endVisibility) {
- return true;
- }
-
- /**
- * The default implementation of this method does nothing. Subclasses
- * should override if they need to do anything when target objects
- * appear during the scene change.
- * @param sceneRoot
- * @param startValues
- * @param startVisibility
- * @param endValues
- * @param endVisibility
- */
- protected Animator appear(ViewGroup sceneRoot,
- TransitionValues startValues, int startVisibility,
- TransitionValues endValues, int endVisibility) {
- return null;
- }
-
- /**
- * The default implementation of this method does nothing. Subclasses
- * should override if they need to do anything when target objects
- * disappear during the scene change.
- * @param sceneRoot
- * @param startValues
- * @param startVisibility
- * @param endValues
- * @param endVisibility
- */
protected Animator disappear(ViewGroup sceneRoot,
TransitionValues startValues, int startVisibility,
TransitionValues endValues, int endVisibility) {
diff --git a/tests/TransitionTests/AndroidManifest.xml b/tests/TransitionTests/AndroidManifest.xml
index 3861164717f5..5483f6490948 100644
--- a/tests/TransitionTests/AndroidManifest.xml
+++ b/tests/TransitionTests/AndroidManifest.xml
@@ -226,6 +226,13 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
+ <activity android:label="HierarchicalMove"
+ android:name=".HierarchicalMove">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
</application>
diff --git a/tests/TransitionTests/res/layout/hierarchical_move.xml b/tests/TransitionTests/res/layout/hierarchical_move.xml
new file mode 100644
index 000000000000..1e70ba96d062
--- /dev/null
+++ b/tests/TransitionTests/res/layout/hierarchical_move.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:id="@+id/container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/submit"
+ android:onClick="sendMessage"
+ android:id="@+id/sceneSwitchButton"/>
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/button0"
+ android:id="@+id/button0"/>
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/button1"
+ android:id="@+id/button1"/>
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/button2"
+ android:id="@+id/button2"/>
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/button3"
+ android:id="@+id/button3"/>
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/button4"
+ android:id="@+id/button4"/>
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/button5"
+ android:id="@+id/button5"/>
+
+</LinearLayout> \ No newline at end of file
diff --git a/tests/TransitionTests/res/values/strings.xml b/tests/TransitionTests/res/values/strings.xml
index 3be243bbcdd4..9b80a265e1ad 100644
--- a/tests/TransitionTests/res/values/strings.xml
+++ b/tests/TransitionTests/res/values/strings.xml
@@ -43,4 +43,10 @@
<string name="state2">State 2</string>
<string name="state3">State 3</string>
<string name="state4">State 4</string>
+ <string name="button0">Button 0</string>
+ <string name="button1">Button 1</string>
+ <string name="button2">Button 2</string>
+ <string name="button3">Button 3</string>
+ <string name="button4">Button 4</string>
+ <string name="button5">Button 5</string>
</resources>
diff --git a/tests/TransitionTests/src/com/android/transitiontests/HierarchicalMove.java b/tests/TransitionTests/src/com/android/transitiontests/HierarchicalMove.java
new file mode 100644
index 000000000000..093d7c1931a0
--- /dev/null
+++ b/tests/TransitionTests/src/com/android/transitiontests/HierarchicalMove.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.transitiontests;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.transition.Move;
+import android.view.transition.Transition;
+import android.view.transition.TransitionGroup;
+import android.view.transition.TransitionManager;
+import android.widget.Button;
+
+import static android.widget.LinearLayout.LayoutParams;
+
+public class HierarchicalMove extends Activity {
+
+ Button[] buttons = new Button[6];
+ ViewGroup mSceneRoot;
+ boolean wide = false;
+ Transition mTransition;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.hierarchical_move);
+
+ View container = (View) findViewById(R.id.container);
+ mSceneRoot = (ViewGroup) container.getParent();
+
+ buttons[0] = (Button) findViewById(R.id.button0);
+ buttons[1] = (Button) findViewById(R.id.button1);
+ buttons[2] = (Button) findViewById(R.id.button2);
+ buttons[3] = (Button) findViewById(R.id.button3);
+ buttons[4] = (Button) findViewById(R.id.button4);
+ buttons[5] = (Button) findViewById(R.id.button5);
+
+ // Move button0, then buttons 1/2 together, then buttons 3/4/5 sequentially:
+ // group (seq)
+ // Move 0
+ // group (seq)
+ // group (together)
+ // Move 1
+ // Move 2
+ // group (sequentially)
+ // Move 3
+ // Move 4/5
+ TransitionGroup rootTransition = new TransitionGroup(TransitionGroup.SEQUENTIALLY);
+
+ // button0
+ Transition move0 = new Move();
+ move0.setTargets(buttons[0]);
+
+ // buttons 1/2/3/4/5
+ TransitionGroup group12345 = new TransitionGroup(TransitionGroup.SEQUENTIALLY);
+
+ // buttons 1/2
+ TransitionGroup group12 = new TransitionGroup(TransitionGroup.TOGETHER);
+ Move move1 = new Move();
+ move1.setTargets(buttons[1]);
+ Move move2 = new Move();
+ move2.setTargets(buttons[2]);
+ group12.addTransitions(move1, move2);
+
+ TransitionGroup group345 = new TransitionGroup(TransitionGroup.SEQUENTIALLY);
+ Move move3 = new Move();
+ move3.setTargets(buttons[3]);
+ Move move45 = new Move();
+ move45.setTargets(buttons[4], buttons[5]);
+ group345.addTransitions(move3, move45);
+
+ group12345.addTransitions(move0, group12, group345);
+
+ rootTransition.addTransitions(group12345);
+ rootTransition.setDuration(1000);
+ mTransition = rootTransition;
+
+ }
+
+ public void sendMessage(View view) {
+ TransitionManager.beginDelayedTransition(mSceneRoot, mTransition);
+ int widthSpec = wide ? LayoutParams.WRAP_CONTENT : LayoutParams.MATCH_PARENT;
+ LayoutParams params = new LayoutParams(widthSpec, LayoutParams.WRAP_CONTENT);
+ for (int i = 0; i < buttons.length; ++i) {
+ buttons[i].setLayoutParams(params);
+ }
+ wide = !wide;
+ }
+
+}