diff --git a/api/current.txt b/api/current.txt
index f884bf47c2a04..a896ecb8025a3 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -28547,28 +28547,30 @@ package android.view.transition {
method protected android.animation.Animator play(android.view.ViewGroup, android.view.transition.TransitionValues, android.view.transition.TransitionValues);
}
- public abstract class Transition {
+ public abstract class Transition implements java.lang.Cloneable {
ctor public Transition();
method public void addListener(android.view.transition.Transition.TransitionListener);
method protected void cancelTransition();
method protected abstract void captureValues(android.view.transition.TransitionValues, boolean);
+ method public android.view.transition.Transition clone();
method public long getDuration();
method public android.animation.TimeInterpolator getInterpolator();
method public java.util.ArrayList getListeners();
method public long getStartDelay();
method public int[] getTargetIds();
method public android.view.View[] getTargets();
+ method protected android.view.transition.TransitionValues getTransitionValues(android.view.View, boolean);
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 boolean prePlay(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,12 +28620,12 @@ package android.view.transition {
public abstract class Visibility extends android.view.transition.Transition {
ctor public Visibility();
- method protected android.animation.Animator appear(android.view.ViewGroup, android.view.View, int, android.view.View, int);
+ 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.View, int, android.view.View, int);
+ 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 preAppear(android.view.ViewGroup, android.view.View, int, android.view.View, int);
- method protected boolean preDisappear(android.view.ViewGroup, android.view.View, int, android.view.View, int);
+ 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/AutoTransition.java b/core/java/android/view/transition/AutoTransition.java
index d94cf2c42438b..7ddac7e08c8ea 100644
--- a/core/java/android/view/transition/AutoTransition.java
+++ b/core/java/android/view/transition/AutoTransition.java
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package android.view.transition;
/**
diff --git a/core/java/android/view/transition/Crossfade.java b/core/java/android/view/transition/Crossfade.java
index a40d0bf9987dc..1e9b6fa56ca8d 100644
--- a/core/java/android/view/transition/Crossfade.java
+++ b/core/java/android/view/transition/Crossfade.java
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package android.view.transition;
import android.animation.Animator;
@@ -139,7 +140,7 @@ public class Crossfade extends Transition {
}
@Override
- protected boolean prePlay(ViewGroup sceneRoot, TransitionValues startValues,
+ protected boolean setup(ViewGroup sceneRoot, TransitionValues startValues,
TransitionValues endValues) {
if (startValues == null || endValues == null) {
return false;
diff --git a/core/java/android/view/transition/Fade.java b/core/java/android/view/transition/Fade.java
index 8e4909dbfbe37..f3a4a392a1e9e 100644
--- a/core/java/android/view/transition/Fade.java
+++ b/core/java/android/view/transition/Fade.java
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package android.view.transition;
import android.animation.Animator;
@@ -32,6 +33,8 @@ import android.view.ViewGroup;
public class Fade extends Visibility {
private static final String LOG_TAG = "Fade";
+ private static final String PROPNAME_SCREEN_X = "android:fade:screenX";
+ private static final String PROPNAME_SCREEN_Y = "android:fade:screenY";
/**
* Fading mode used in {@link #Fade(int)} to make the transition
@@ -81,8 +84,19 @@ public class Fade extends Visibility {
}
@Override
- protected boolean preAppear(ViewGroup sceneRoot, View startView, int startVisibility,
- View endView, int endVisibility) {
+ protected void captureValues(TransitionValues values, boolean start) {
+ super.captureValues(values, start);
+ int[] loc = new int[2];
+ values.view.getLocationOnScreen(loc);
+ values.values.put(PROPNAME_SCREEN_X, loc[0]);
+ values.values.put(PROPNAME_SCREEN_Y, loc[1]);
+ }
+
+ @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;
}
@@ -91,27 +105,32 @@ public class Fade extends Visibility {
}
@Override
- protected Animator appear(ViewGroup sceneRoot, View startView, int startVisibility,
- View endView, int endVisibility) {
+ protected Animator appear(ViewGroup sceneRoot,
+ TransitionValues startValues, int startVisibility,
+ TransitionValues endValues, int endVisibility) {
+ View endView = (endValues != null) ? endValues.view : null;
if ((mFadingMode & IN) != IN) {
return null;
}
- // TODO: hack - retain original value from before preAppear
+ // TODO: hack - retain original value from before setupAppear
return runAnimation(endView, 0, 1, null);
// TODO: end listener to make sure we end at 1 no matter what
}
@Override
- protected boolean preDisappear(ViewGroup sceneRoot, View startView, int startVisibility,
- View endView, int endVisibility) {
+ protected boolean setupDisappear(ViewGroup sceneRoot,
+ TransitionValues startValues, int startVisibility,
+ TransitionValues endValues, int endVisibility) {
if ((mFadingMode & OUT) != OUT) {
return false;
}
+ View view;
+ View startView = (startValues != null) ? startValues.view : null;
+ View endView = (endValues != null) ? endValues.view : null;
if (Transition.DBG) {
Log.d(LOG_TAG, "Fade.predisappear: startView, startVis, endView, endVis = " +
startView + ", " + startVisibility + ", " + endView + ", " + endVisibility);
}
- View view;
View overlayView = null;
View viewToKeep = null;
if (endView == null) {
@@ -137,6 +156,12 @@ public class Fade extends Visibility {
// 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
+ int screenX = (Integer) startValues.values.get(PROPNAME_SCREEN_X);
+ int screenY = (Integer) startValues.values.get(PROPNAME_SCREEN_Y);
+ int[] loc = new int[2];
+ sceneRoot.getLocationOnScreen(loc);
+ overlayView.offsetLeftAndRight((screenX - loc[0]) - overlayView.getLeft());
+ overlayView.offsetTopAndBottom((screenY - loc[1]) - overlayView.getTop());
sceneRoot.getOverlay().add(overlayView);
return true;
}
@@ -150,11 +175,14 @@ public class Fade extends Visibility {
}
@Override
- protected Animator disappear(ViewGroup sceneRoot, View startView, int startVisibility,
- View endView, int endVisibility) {
+ 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);
diff --git a/core/java/android/view/transition/Move.java b/core/java/android/view/transition/Move.java
index 1d05419c4613d..5c9da887819a0 100644
--- a/core/java/android/view/transition/Move.java
+++ b/core/java/android/view/transition/Move.java
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package android.view.transition;
import android.animation.Animator;
@@ -212,7 +213,7 @@ public class Move extends Transition {
}
@Override
- protected boolean prePlay(final ViewGroup sceneRoot, TransitionValues startValues,
+ protected boolean setup(final ViewGroup sceneRoot, TransitionValues startValues,
TransitionValues endValues) {
if (startValues == null || endValues == null) {
return false;
diff --git a/core/java/android/view/transition/Recolor.java b/core/java/android/view/transition/Recolor.java
index 45407e1f2872e..217996059ad12 100644
--- a/core/java/android/view/transition/Recolor.java
+++ b/core/java/android/view/transition/Recolor.java
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package android.view.transition;
import android.animation.Animator;
@@ -50,7 +51,7 @@ public class Recolor extends Transition {
}
@Override
- protected boolean prePlay(ViewGroup sceneRoot, TransitionValues startValues,
+ protected boolean setup(ViewGroup sceneRoot, TransitionValues startValues,
TransitionValues endValues) {
if (startValues == null || endValues == null) {
return false;
diff --git a/core/java/android/view/transition/Rotate.java b/core/java/android/view/transition/Rotate.java
index b42fbe524dd89..8d579d2b8cdf1 100644
--- a/core/java/android/view/transition/Rotate.java
+++ b/core/java/android/view/transition/Rotate.java
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package android.view.transition;
import android.animation.Animator;
@@ -34,7 +35,7 @@ public class Rotate extends Transition {
}
@Override
- protected boolean prePlay(ViewGroup sceneRoot, TransitionValues startValues,
+ protected boolean setup(ViewGroup sceneRoot, TransitionValues startValues,
TransitionValues endValues) {
if (startValues == null || endValues == null) {
return false;
diff --git a/core/java/android/view/transition/Scene.java b/core/java/android/view/transition/Scene.java
index 62cb9d378297a..cf3eadb584e46 100644
--- a/core/java/android/view/transition/Scene.java
+++ b/core/java/android/view/transition/Scene.java
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package android.view.transition;
import android.content.Context;
diff --git a/core/java/android/view/transition/Slide.java b/core/java/android/view/transition/Slide.java
index 8630ee2dc6f6f..e39daa6c08062 100644
--- a/core/java/android/view/transition/Slide.java
+++ b/core/java/android/view/transition/Slide.java
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package android.view.transition;
import android.animation.Animator;
@@ -36,8 +37,10 @@ public class Slide extends Visibility {
private static final TimeInterpolator sDecelerator = new DecelerateInterpolator();
@Override
- protected Animator appear(ViewGroup sceneRoot, View startView, int startVisibility,
- View endView, int endVisibility) {
+ protected Animator appear(ViewGroup sceneRoot,
+ TransitionValues startValues, int startVisibility,
+ TransitionValues endValues, int endVisibility) {
+ View endView = (endValues != null) ? endValues.view : null;
ObjectAnimator anim = ObjectAnimator.ofFloat(endView, View.TRANSLATION_Y,
-2 * endView.getHeight(), 0);
anim.setInterpolator(sDecelerator);
@@ -45,22 +48,28 @@ public class Slide extends Visibility {
}
@Override
- protected boolean preAppear(ViewGroup sceneRoot, View startView, int startVisibility,
- View endView, int endVisibility) {
+ 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 preDisappear(ViewGroup sceneRoot, View startView, int startVisibility,
- View endView, int endVisibility) {
+ 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, View startView, int startVisibility,
- View endView, int endVisibility) {
+ protected Animator disappear(ViewGroup sceneRoot,
+ TransitionValues startValues, int startVisibility,
+ TransitionValues endValues, int endVisibility) {
+ View startView = (startValues != null) ? startValues.view : null;
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 ac2852cbb3dbd..16e990fd58b45 100644
--- a/core/java/android/view/transition/TextChange.java
+++ b/core/java/android/view/transition/TextChange.java
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package android.view.transition;
import android.animation.Animator;
@@ -46,7 +47,7 @@ public class TextChange extends Transition {
}
@Override
- protected boolean prePlay(ViewGroup sceneRoot, TransitionValues startValues,
+ protected boolean setup(ViewGroup sceneRoot, TransitionValues startValues,
TransitionValues endValues) {
if (startValues == null || endValues == null || !(endValues.view instanceof TextView)) {
return false;
diff --git a/core/java/android/view/transition/Transition.java b/core/java/android/view/transition/Transition.java
index 205c825e6b0b0..fd12339485c90 100644
--- a/core/java/android/view/transition/Transition.java
+++ b/core/java/android/view/transition/Transition.java
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package android.view.transition;
import android.animation.Animator;
@@ -52,7 +53,7 @@ import java.util.ArrayList;
* with TextureView because they rely on {@link ViewOverlay} functionality,
* which does not currently work with TextureView.
*/
-public abstract class Transition {
+public abstract class Transition implements Cloneable {
private static final String LOG_TAG = "Transition";
static final boolean DBG = false;
@@ -62,18 +63,14 @@ public abstract class Transition {
TimeInterpolator mInterpolator = null;
int[] mTargetIds;
View[] mTargets;
- private ArrayMap mStartValues =
- new ArrayMap();
- private SparseArray mStartIdValues = new SparseArray();
- private LongSparseArray mStartItemIdValues =
- new LongSparseArray();
- private ArrayMap mEndValues =
- new ArrayMap();
- private SparseArray mEndIdValues = new SparseArray();
- private LongSparseArray mEndItemIdValues =
- new LongSparseArray();
+ private TransitionValuesMaps mStartValues = new TransitionValuesMaps();
+ private TransitionValuesMaps mEndValues = new TransitionValuesMaps();
+ TransitionGroup mParent = null;
- // Used to carry data between preplay() and play(), cleared before every scene transition
+ // Scene Root is set at play() time in the cloned Transition
+ ViewGroup mSceneRoot = null;
+
+ // Used to carry data between setup() and play(), cleared before every scene transition
private ArrayList mPlayStartValuesList = new ArrayList();
private ArrayList mPlayEndValuesList = new ArrayList();
@@ -185,7 +182,7 @@ public abstract class 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 preplay() method.
+ * different value should set that value in the setup() method.
*
*
Additionally, a Transition can perform logic to determine whether
* the transition needs to run on the given target and start/end values.
@@ -206,19 +203,19 @@ public abstract class Transition {
* TransitionValues, TransitionValues) play()} method should be called
* during this scene change, false otherwise.
*/
- protected boolean prePlay(ViewGroup sceneRoot, TransitionValues startValues,
+ protected boolean setup(ViewGroup sceneRoot, TransitionValues startValues,
TransitionValues endValues) {
return true;
}
/**
- * This version of prePlay() is called with the entire set of start/end
+ * This version of setup() is called with the entire set of start/end
* values. The implementation in Transition iterates through these lists
- * and calls {@link #prePlay(ViewGroup, TransitionValues, TransitionValues)}
+ * and calls {@link #setup(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
- * preplay() out from play() is to allow all Transitions in the tree to
+ * 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
@@ -226,32 +223,29 @@ public abstract class Transition {
*
* @hide
*/
- protected void prePlay(ViewGroup sceneRoot, ArrayMap startValues,
- SparseArray startIdValues,
- LongSparseArray startItemIdValues,
- ArrayMap endValues,
- SparseArray endIdValues,
- LongSparseArray endItemIdValues) {
+ protected void setup(ViewGroup sceneRoot, TransitionValuesMaps startValues,
+ TransitionValuesMaps endValues) {
mPlayStartValuesList.clear();
mPlayEndValuesList.clear();
- ArrayMap endCopy = new ArrayMap(endValues);
+ ArrayMap endCopy =
+ new ArrayMap(endValues.viewValues);
SparseArray endIdCopy =
- new SparseArray(endIdValues.size());
- for (int i = 0; i < endIdValues.size(); ++i) {
- int id = endIdValues.keyAt(i);
- endIdCopy.put(id, endIdValues.valueAt(i));
+ new SparseArray(endValues.idValues.size());
+ for (int i = 0; i < endValues.idValues.size(); ++i) {
+ int id = endValues.idValues.keyAt(i);
+ endIdCopy.put(id, endValues.idValues.valueAt(i));
}
LongSparseArray endItemIdCopy =
- new LongSparseArray(endItemIdValues.size());
- for (int i = 0; i < endItemIdValues.size(); ++i) {
- long id = endItemIdValues.keyAt(i);
- endItemIdCopy.put(id, endItemIdValues.valueAt(i));
+ new LongSparseArray(endValues.itemIdValues.size());
+ for (int i = 0; i < endValues.itemIdValues.size(); ++i) {
+ long id = endValues.itemIdValues.keyAt(i);
+ endItemIdCopy.put(id, endValues.itemIdValues.valueAt(i));
}
// Walk through the start values, playing everything we find
// Remove from the end set as we go
ArrayList startValuesList = new ArrayList();
ArrayList endValuesList = new ArrayList();
- for (View view : startValues.keySet()) {
+ for (View view : startValues.viewValues.keySet()) {
TransitionValues start = null;
TransitionValues end = null;
boolean isInListView = false;
@@ -260,13 +254,13 @@ public abstract class Transition {
}
if (!isInListView) {
int id = view.getId();
- start = startValues.get(view) != null ?
- startValues.get(view) : startIdValues.get(id);
- if (endValues.get(view) != null) {
- end = endValues.get(view);
+ start = startValues.viewValues.get(view) != null ?
+ startValues.viewValues.get(view) : startValues.idValues.get(id);
+ if (endValues.viewValues.get(view) != null) {
+ end = endValues.viewValues.get(view);
endCopy.remove(view);
} else {
- end = endIdValues.get(id);
+ end = endValues.idValues.get(id);
View removeView = null;
for (View viewToRemove : endCopy.keySet()) {
if (viewToRemove.getId() == id) {
@@ -287,7 +281,7 @@ public abstract class Transition {
if (parent.getAdapter().hasStableIds()) {
int position = parent.getPositionForView(view);
long itemId = parent.getItemIdAtPosition(position);
- start = startItemIdValues.get(itemId);
+ start = startValues.itemIdValues.get(itemId);
endItemIdCopy.remove(itemId);
// TODO: deal with targetIDs for itemIDs for ListView items
startValuesList.add(start);
@@ -295,12 +289,12 @@ public abstract class Transition {
}
}
}
- int startItemIdCopySize = startItemIdValues.size();
+ int startItemIdCopySize = startValues.itemIdValues.size();
for (int i = 0; i < startItemIdCopySize; ++i) {
- long id = startItemIdValues.keyAt(i);
+ long id = startValues.itemIdValues.keyAt(i);
if (isValidTarget(null, id)) {
- TransitionValues start = startItemIdValues.get(id);
- TransitionValues end = endItemIdValues.get(id);
+ TransitionValues start = startValues.itemIdValues.get(id);
+ TransitionValues end = endValues.itemIdValues.get(id);
endItemIdCopy.remove(id);
startValuesList.add(start);
endValuesList.add(end);
@@ -310,8 +304,8 @@ public abstract class Transition {
for (View view : endCopy.keySet()) {
int id = view.getId();
if (isValidTarget(view, id)) {
- TransitionValues start = startValues.get(view) != null ?
- startValues.get(view) : startIdValues.get(id);
+ TransitionValues start = startValues.viewValues.get(view) != null ?
+ startValues.viewValues.get(view) : startValues.idValues.get(id);
TransitionValues end = endCopy.get(view);
endIdCopy.remove(id);
startValuesList.add(start);
@@ -322,7 +316,7 @@ public abstract class Transition {
for (int i = 0; i < endIdCopySize; ++i) {
int id = endIdCopy.keyAt(i);
if (isValidTarget(null, id)) {
- TransitionValues start = startIdValues.get(id);
+ TransitionValues start = startValues.idValues.get(id);
TransitionValues end = endIdCopy.get(id);
startValuesList.add(start);
endValuesList.add(end);
@@ -332,7 +326,7 @@ public abstract class Transition {
for (int i = 0; i < endItemIdCopySize; ++i) {
long id = endItemIdCopy.keyAt(i);
// TODO: Deal with targetIDs and itemIDs
- TransitionValues start = startItemIdValues.get(id);
+ TransitionValues start = startValues.itemIdValues.get(id);
TransitionValues end = endItemIdCopy.get(id);
startValuesList.add(start);
endValuesList.add(end);
@@ -341,7 +335,7 @@ public abstract class Transition {
TransitionValues start = startValuesList.get(i);
TransitionValues end = endValuesList.get(i);
// TODO: what to do about targetIds and itemIds?
- if (prePlay(sceneRoot, start, end)) {
+ if (setup(sceneRoot, start, end)) {
// Note: we've already done the check against targetIDs in these lists
mPlayStartValuesList.add(start);
mPlayEndValuesList.add(end);
@@ -390,13 +384,7 @@ public abstract class Transition {
*
* @hide
*/
- protected void play(ViewGroup sceneRoot,
- final ArrayMap startValues,
- final SparseArray startIdValues,
- final LongSparseArray startItemIdValues,
- final ArrayMap endValues,
- final SparseArray endIdValues,
- final LongSparseArray endItemIdValues) {
+ protected void play(ViewGroup sceneRoot) {
startTransition();
// Now walk the list of TransitionValues, calling play for each pair
@@ -436,7 +424,7 @@ public abstract class Transition {
* start. 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 preplay and play() methods to determine what, if any,
+ * later during the setup() and play() methods to determine what, if any,
* animations, should be run.
*
* @param transitionValues The holder any values that the Transition
@@ -553,14 +541,14 @@ public abstract class Transition {
values.view = view;
captureValues(values, start);
if (start) {
- mStartValues.put(view, values);
+ mStartValues.viewValues.put(view, values);
if (id >= 0) {
- mStartIdValues.put(id, values);
+ mStartValues.idValues.put(id, values);
}
} else {
- mEndValues.put(view, values);
+ mEndValues.viewValues.put(view, values);
if (id >= 0) {
- mEndIdValues.put(id, values);
+ mEndValues.idValues.put(id, values);
}
}
}
@@ -574,9 +562,9 @@ public abstract class Transition {
values.view = view;
captureValues(values, start);
if (start) {
- mStartValues.put(view, values);
+ mStartValues.viewValues.put(view, values);
} else {
- mEndValues.put(view, values);
+ mEndValues.viewValues.put(view, values);
}
}
}
@@ -622,21 +610,21 @@ public abstract class Transition {
captureValues(values, start);
if (start) {
if (!isListViewItem) {
- mStartValues.put(view, values);
+ mStartValues.viewValues.put(view, values);
if (id >= 0) {
- mStartIdValues.put((int) id, values);
+ mStartValues.idValues.put((int) id, values);
}
} else {
- mStartItemIdValues.put(id, values);
+ mStartValues.itemIdValues.put(id, values);
}
} else {
if (!isListViewItem) {
- mEndValues.put(view, values);
+ mEndValues.viewValues.put(view, values);
if (id >= 0) {
- mEndIdValues.put((int) id, values);
+ mEndValues.idValues.put((int) id, values);
}
} else {
- mEndItemIdValues.put(id, values);
+ mEndValues.itemIdValues.put(id, values);
}
}
if (view instanceof ViewGroup) {
@@ -647,19 +635,46 @@ public abstract class Transition {
}
}
+ /**
+ * This method can be called by transitions to get the TransitionValues for
+ * any particular view during the transition-playing process. This might be
+ * necessary, for example, to query the before/after state of related views
+ * for a given transition.
+ */
+ protected TransitionValues getTransitionValues(View view, boolean start) {
+ if (mParent != null) {
+ return mParent.getTransitionValues(view, start);
+ }
+ TransitionValuesMaps valuesMaps = start ? mStartValues : mEndValues;
+ TransitionValues values = valuesMaps.viewValues.get(view);
+ if (values == null) {
+ int id = view.getId();
+ if (id >= 0) {
+ values = valuesMaps.idValues.get(id);
+ }
+ if (values == null && view.getParent() instanceof ListView) {
+ ListView listview = (ListView) view.getParent();
+ int position = listview.getPositionForView(view);
+ long itemId = listview.getItemIdAtPosition(position);
+ values = valuesMaps.itemIdValues.get(itemId);
+ }
+ // TODO: Doesn't handle the case where a view was parented to a
+ // ListView (with an itemId), but no longer is
+ }
+ return values;
+ }
+
/**
* Called by TransitionManager to play the transition. This calls
- * prePlay() and then play() with the full set of per-view
+ * setup() and then play() with the full set of per-view
* transitionValues objects
*/
- void play(ViewGroup sceneRoot) {
- // prePlay() must be called on entire transition hierarchy and set of views
+ 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
- prePlay(sceneRoot, mStartValues, mStartIdValues, mStartItemIdValues,
- mEndValues, mEndIdValues, mEndItemIdValues);
- play(sceneRoot, mStartValues, mStartIdValues, mStartItemIdValues,
- mEndValues, mEndIdValues, mEndItemIdValues);
+ setup(sceneRoot, mStartValues, mEndValues);
+ play(sceneRoot);
}
/**
@@ -766,26 +781,26 @@ public abstract class Transition {
tmpListeners.get(i).onTransitionEnd(this);
}
}
- for (int i = 0; i < mStartItemIdValues.size(); ++i) {
- TransitionValues tv = mStartItemIdValues.valueAt(i);
+ for (int i = 0; i < mStartValues.itemIdValues.size(); ++i) {
+ TransitionValues tv = mStartValues.itemIdValues.valueAt(i);
View v = tv.view;
if (v.hasTransientState()) {
v.setHasTransientState(false);
}
}
- for (int i = 0; i < mEndItemIdValues.size(); ++i) {
- TransitionValues tv = mEndItemIdValues.valueAt(i);
+ for (int i = 0; i < mEndValues.itemIdValues.size(); ++i) {
+ TransitionValues tv = mEndValues.itemIdValues.valueAt(i);
View v = tv.view;
if (v.hasTransientState()) {
v.setHasTransientState(false);
}
}
- mStartValues.clear();
- mStartIdValues.clear();
- mStartItemIdValues.clear();
- mEndValues.clear();
- mEndIdValues.clear();
- mEndItemIdValues.clear();
+ mStartValues.viewValues.clear();
+ mStartValues.idValues.clear();
+ mStartValues.itemIdValues.clear();
+ mEndValues.viewValues.clear();
+ mEndValues.idValues.clear();
+ mEndValues.itemIdValues.clear();
mCurrentAnimators.clear();
}
}
@@ -853,11 +868,25 @@ public abstract class Transition {
return mListeners;
}
+ void setSceneRoot(ViewGroup sceneRoot) {
+ mSceneRoot = sceneRoot;
+ }
+
@Override
public String toString() {
return toString("");
}
+ @Override
+ public Transition clone() {
+ Transition clone = null;
+ try {
+ clone = (Transition) super.clone();
+ } catch (CloneNotSupportedException e) {}
+
+ return clone;
+ }
+
String toString(String indent) {
String result = indent + getClass().getSimpleName() + "@" +
Integer.toHexString(hashCode()) + ": ";
diff --git a/core/java/android/view/transition/TransitionGroup.java b/core/java/android/view/transition/TransitionGroup.java
index 8ff46b63e1c66..6f9a3ef06dfb3 100644
--- a/core/java/android/view/transition/TransitionGroup.java
+++ b/core/java/android/view/transition/TransitionGroup.java
@@ -13,13 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package android.view.transition;
import android.animation.Animator;
import android.util.AndroidRuntimeException;
-import android.util.ArrayMap;
-import android.util.LongSparseArray;
-import android.util.SparseArray;
import android.view.View;
import android.view.ViewGroup;
@@ -106,6 +104,7 @@ public class TransitionGroup extends Transition {
int numTransitions = transitions.length;
for (int i = 0; i < numTransitions; ++i) {
mTransitions.add(transitions[i]);
+ transitions[i].mParent = this;
if (mDuration >= 0) {
transitions[0].setDuration(mDuration);
}
@@ -139,6 +138,7 @@ public class TransitionGroup extends Transition {
*/
public void removeTransition(Transition transition) {
mTransitions.remove(transition);
+ transition.mParent = null;
}
/**
@@ -147,8 +147,9 @@ public class TransitionGroup extends Transition {
* must finish first).
*/
private void setupStartEndListeners() {
+ TransitionGroupListener listener = new TransitionGroupListener(this);
for (Transition childTransition : mTransitions) {
- childTransition.addListener(mListener);
+ childTransition.addListener(listener);
}
mCurrentListeners = mTransitions.size();
}
@@ -157,55 +158,47 @@ public class TransitionGroup extends Transition {
* This listener is used to detect when all child transitions are done, at
* which point this transition group is also done.
*/
- private TransitionListener mListener = new TransitionListenerAdapter() {
+ static class TransitionGroupListener extends TransitionListenerAdapter {
+ TransitionGroup mTransitionGroup;
+ TransitionGroupListener(TransitionGroup transitionGroup) {
+ mTransitionGroup = transitionGroup;
+ }
@Override
public void onTransitionStart(Transition transition) {
- if (!mStarted) {
- startTransition();
- mStarted = true;
+ if (!mTransitionGroup.mStarted) {
+ mTransitionGroup.startTransition();
+ mTransitionGroup.mStarted = true;
}
}
@Override
public void onTransitionEnd(Transition transition) {
- --mCurrentListeners;
- if (mCurrentListeners == 0) {
+ --mTransitionGroup.mCurrentListeners;
+ if (mTransitionGroup.mCurrentListeners == 0) {
// All child trans
- mStarted = false;
- endTransition();
+ mTransitionGroup.mStarted = false;
+ mTransitionGroup.endTransition();
}
transition.removeListener(this);
}
- };
-
- /**
- * @hide
- */
- @Override
- protected void prePlay(ViewGroup sceneRoot,
- ArrayMap startValues,
- SparseArray startIdValues,
- LongSparseArray startItemIdValues,
- ArrayMap endValues,
- SparseArray endIdValues,
- LongSparseArray endItemIdValues) {
- for (Transition childTransition : mTransitions) {
- childTransition.prePlay(sceneRoot, startValues, startIdValues, startItemIdValues,
- endValues, endIdValues, endItemIdValues);
- }
}
/**
* @hide
*/
@Override
- protected void play(ViewGroup sceneRoot,
- final ArrayMap startValues,
- final SparseArray startIdValues,
- final LongSparseArray startItemIdValues,
- final ArrayMap endValues,
- final SparseArray endIdValues,
- final LongSparseArray endItemIdValues) {
+ protected void setup(ViewGroup sceneRoot, TransitionValuesMaps startValues,
+ TransitionValuesMaps endValues) {
+ for (Transition childTransition : mTransitions) {
+ childTransition.setup(sceneRoot, startValues, endValues);
+ }
+ }
+
+ /**
+ * @hide
+ */
+ @Override
+ protected void play(ViewGroup sceneRoot) {
setupStartEndListeners();
final ViewGroup finalSceneRoot = sceneRoot;
if (!mPlayTogether) {
@@ -217,22 +210,18 @@ public class TransitionGroup extends Transition {
previousTransition.addListener(new TransitionListenerAdapter() {
@Override
public void onTransitionEnd(Transition transition) {
- nextTransition.play(finalSceneRoot,
- startValues, startIdValues, startItemIdValues,
- endValues, endIdValues, endItemIdValues);
+ nextTransition.play(finalSceneRoot);
transition.removeListener(this);
}
});
}
Transition firstTransition = mTransitions.get(0);
if (firstTransition != null) {
- firstTransition.play(finalSceneRoot, startValues, startIdValues, startItemIdValues,
- endValues, endIdValues, endItemIdValues);
+ firstTransition.play(finalSceneRoot);
}
} else {
for (Transition childTransition : mTransitions) {
- childTransition.play(finalSceneRoot, startValues, startIdValues, startItemIdValues,
- endValues, endIdValues, endItemIdValues);
+ childTransition.play(finalSceneRoot);
}
}
}
@@ -311,6 +300,15 @@ public class TransitionGroup extends Transition {
}
}
+ @Override
+ void setSceneRoot(ViewGroup sceneRoot) {
+ super.setSceneRoot(sceneRoot);
+ int numTransitions = mTransitions.size();
+ for (int i = 0; i < numTransitions; ++i) {
+ mTransitions.get(i).setSceneRoot(sceneRoot);
+ }
+ }
+
@Override
String toString(String indent) {
String result = super.toString(indent);
@@ -320,4 +318,15 @@ public class TransitionGroup extends Transition {
return result;
}
+ @Override
+ public TransitionGroup clone() {
+ TransitionGroup clone = (TransitionGroup) super.clone();
+ clone.mTransitions = new ArrayList();
+ int numTransitions = mTransitions.size();
+ for (int i = 0; i < numTransitions; ++i) {
+ clone.mTransitions.add((Transition) mTransitions.get(i).clone());
+ }
+ return clone;
+ }
+
}
diff --git a/core/java/android/view/transition/TransitionInflater.java b/core/java/android/view/transition/TransitionInflater.java
index dc930d5fb2e95..be658af0c86f8 100644
--- a/core/java/android/view/transition/TransitionInflater.java
+++ b/core/java/android/view/transition/TransitionInflater.java
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package android.view.transition;
import android.content.Context;
diff --git a/core/java/android/view/transition/TransitionManager.java b/core/java/android/view/transition/TransitionManager.java
index 8088f6b2c23da..59b07b196e2fd 100644
--- a/core/java/android/view/transition/TransitionManager.java
+++ b/core/java/android/view/transition/TransitionManager.java
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package android.view.transition;
import android.util.ArrayMap;
@@ -142,15 +143,18 @@ public class TransitionManager {
* @param scene The scene being entered
* @param transition The transition to play for this scene change
*/
- private static void changeScene(Scene scene, final Transition transition) {
+ private static void changeScene(Scene scene, Transition transition) {
final ViewGroup sceneRoot = scene.getSceneRoot();
- sceneChangeSetup(sceneRoot, transition);
+ Transition transitionClone = transition.clone();
+ transitionClone.setSceneRoot(sceneRoot);
+
+ sceneChangeSetup(sceneRoot, transitionClone);
scene.enter();
- sceneChangeRunTransition(sceneRoot, transition);
+ sceneChangeRunTransition(sceneRoot, transitionClone);
}
private static void sceneChangeRunTransition(final ViewGroup sceneRoot,
@@ -169,7 +173,7 @@ public class TransitionManager {
}
});
transition.captureValues(sceneRoot, false);
- transition.play(sceneRoot);
+ transition.playTransition(sceneRoot);
return true;
}
});
@@ -317,7 +321,7 @@ public class TransitionManager {
if (transition == null) {
transition = sDefaultTransition;
}
- final Transition finalTransition = transition;
+ final Transition finalTransition = transition.clone();
sceneChangeSetup(sceneRoot, transition);
sceneRoot.setCurrentScene(null);
sceneRoot.postOnAnimation(new Runnable() {
diff --git a/core/java/android/view/transition/TransitionValues.java b/core/java/android/view/transition/TransitionValues.java
index 1ef6bf438e145..963e04dac1e88 100644
--- a/core/java/android/view/transition/TransitionValues.java
+++ b/core/java/android/view/transition/TransitionValues.java
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package android.view.transition;
import android.util.ArrayMap;
@@ -36,7 +37,7 @@ import java.util.Map;
* 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#prePlay(ViewGroup, TransitionValues, TransitionValues)} and
+ * for {@link Transition#setup(ViewGroup, TransitionValues, TransitionValues)} and
* for {@link Transition#play(ViewGroup, TransitionValues, TransitionValues)}.
*/
public class TransitionValues {
@@ -55,7 +56,10 @@ public class TransitionValues {
public String toString() {
String returnValue = "TransitionValues@" + Integer.toHexString(hashCode()) + ":\n";
returnValue += " view = " + view + "\n";
- returnValue += " values = " + values + "\n";
+ returnValue += " values:";
+ for (String s : values.keySet()) {
+ returnValue += " " + s + ": " + values.get(s) + "\n";
+ }
return returnValue;
}
}
\ No newline at end of file
diff --git a/core/java/android/view/transition/TransitionValuesMaps.java b/core/java/android/view/transition/TransitionValuesMaps.java
new file mode 100644
index 0000000000000..4cfce4d2da863
--- /dev/null
+++ b/core/java/android/view/transition/TransitionValuesMaps.java
@@ -0,0 +1,30 @@
+/*
+ * 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 android.view.transition;
+
+import android.util.ArrayMap;
+import android.util.LongSparseArray;
+import android.util.SparseArray;
+import android.view.View;
+
+class TransitionValuesMaps {
+ ArrayMap viewValues =
+ new ArrayMap();
+ SparseArray idValues = new SparseArray();
+ LongSparseArray itemIdValues =
+ new LongSparseArray();
+}
diff --git a/core/java/android/view/transition/Visibility.java b/core/java/android/view/transition/Visibility.java
index a3e6e7704792b..c9dba6bfff196 100644
--- a/core/java/android/view/transition/Visibility.java
+++ b/core/java/android/view/transition/Visibility.java
@@ -13,11 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package android.view.transition;
import android.animation.Animator;
import android.view.View;
import android.view.ViewGroup;
+import android.view.ViewParent;
/**
* This transition tracks changes to the visibility of target views in the
@@ -27,16 +29,28 @@ import android.view.ViewGroup;
* 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 #preAppear(ViewGroup, View, int, View, int)},
- * {@link #preDisappear(ViewGroup, View, int, View, int)},
- * {@link #appear(ViewGroup, View, int, View, int)}, and
- * {@link #disappear(ViewGroup, View, int, View, int)}.
+ * {@link #setupAppear(ViewGroup, TransitionValues, int, TransitionValues, int)},
+ * {@link #setupDisappear(ViewGroup, TransitionValues, int, TransitionValues, int)},
+ * {@link #appear(ViewGroup, TransitionValues, int, TransitionValues, int)}, and
+ * {@link #disappear(ViewGroup, TransitionValues, int, TransitionValues, int)}.
*/
public abstract class Visibility extends Transition {
private static final String PROPNAME_VISIBILITY = "android:visibility:visibility";
private static final String PROPNAME_PARENT = "android:visibility:parent";
+ private static class VisibilityInfo {
+ boolean visibilityChange;
+ boolean fadeIn;
+ int startVisibility;
+ int endVisibility;
+ View startParent;
+ View endParent;
+ }
+
+ // Temporary structure, used in calculating state in setup() and play()
+ private VisibilityInfo mTmpVisibilityInfo = new VisibilityInfo();
+
@Override
protected void captureValues(TransitionValues values, boolean start) {
int visibility = values.view.getVisibility();
@@ -44,138 +58,121 @@ public abstract class Visibility extends Transition {
values.values.put(PROPNAME_PARENT, values.view.getParent());
}
- @Override
- protected boolean prePlay(ViewGroup sceneRoot, TransitionValues startValues,
+ private boolean isHierarchyVisibilityChanging(ViewGroup sceneRoot, ViewGroup view) {
+
+ if (view == sceneRoot) {
+ return false;
+ }
+ TransitionValues startValues = getTransitionValues(view, true);
+ TransitionValues endValues = getTransitionValues(view, false);
+
+ if (startValues == null || endValues == null) {
+ return true;
+ }
+ int startVisibility = (Integer) startValues.values.get(PROPNAME_VISIBILITY);
+ View startParent = (View) startValues.values.get(PROPNAME_PARENT);
+ int endVisibility = (Integer) endValues.values.get(PROPNAME_VISIBILITY);
+ View endParent = (View) endValues.values.get(PROPNAME_PARENT);
+ if (startVisibility != endVisibility || startParent != endParent) {
+ return true;
+ }
+
+ ViewParent parent = view.getParent();
+ if (parent instanceof ViewGroup && parent != sceneRoot) {
+ return isHierarchyVisibilityChanging(sceneRoot, (ViewGroup) parent);
+ }
+ return false;
+ }
+
+ private VisibilityInfo getVisibilityChangeInfo(TransitionValues startValues,
TransitionValues endValues) {
- boolean visibilityChange = false;
- boolean fadeIn = false;
- int startVisibility, endVisibility;
- View startParent, endParent;
+ final VisibilityInfo visInfo = mTmpVisibilityInfo;
+ visInfo.visibilityChange = false;
+ visInfo.fadeIn = false;
if (startValues != null) {
- startVisibility = (Integer) startValues.values.get(PROPNAME_VISIBILITY);
- startParent = (View) startValues.values.get(PROPNAME_PARENT);
+ visInfo.startVisibility = (Integer) startValues.values.get(PROPNAME_VISIBILITY);
+ visInfo.startParent = (View) startValues.values.get(PROPNAME_PARENT);
} else {
- startVisibility = -1;
- startParent = null;
+ visInfo.startVisibility = -1;
+ visInfo.startParent = null;
}
if (endValues != null) {
- endVisibility = (Integer) endValues.values.get(PROPNAME_VISIBILITY);
- endParent = (View) endValues.values.get(PROPNAME_PARENT);
+ visInfo.endVisibility = (Integer) endValues.values.get(PROPNAME_VISIBILITY);
+ visInfo.endParent = (View) endValues.values.get(PROPNAME_PARENT);
} else {
- endVisibility = -1;
- endParent = null;
+ visInfo.endVisibility = -1;
+ visInfo.endParent = null;
}
- boolean existenceChange = false;
if (startValues != null && endValues != null) {
- if (startVisibility == endVisibility && startParent == endParent) {
- return false;
+ if (visInfo.startVisibility == visInfo.endVisibility &&
+ visInfo.startParent == visInfo.endParent) {
+ return visInfo;
} else {
- if (startVisibility != endVisibility) {
- if (startVisibility == View.VISIBLE) {
- fadeIn = false;
- visibilityChange = true;
- } else if (endVisibility == View.VISIBLE) {
- fadeIn = true;
- visibilityChange = true;
+ if (visInfo.startVisibility != visInfo.endVisibility) {
+ if (visInfo.startVisibility == View.VISIBLE) {
+ visInfo.fadeIn = false;
+ visInfo.visibilityChange = true;
+ } else if (visInfo.endVisibility == View.VISIBLE) {
+ visInfo.fadeIn = true;
+ visInfo.visibilityChange = true;
}
// no visibilityChange if going between INVISIBLE and GONE
- } else if (startParent != endParent) {
- existenceChange = true;
- if (endParent == null) {
- fadeIn = false;
- visibilityChange = true;
- } else if (startParent == null) {
- fadeIn = true;
- visibilityChange = true;
+ } else if (visInfo.startParent != visInfo.endParent) {
+ if (visInfo.endParent == null) {
+ visInfo.fadeIn = false;
+ visInfo.visibilityChange = true;
+ } else if (visInfo.startParent == null) {
+ visInfo.fadeIn = true;
+ visInfo.visibilityChange = true;
}
}
}
}
if (startValues == null) {
- existenceChange = true;
- fadeIn = true;
- visibilityChange = true;
+ visInfo.fadeIn = true;
+ visInfo.visibilityChange = true;
} else if (endValues == null) {
- existenceChange = true;
- fadeIn = false;
- visibilityChange = true;
+ visInfo.fadeIn = false;
+ visInfo.visibilityChange = true;
}
- if (visibilityChange) {
- if (fadeIn) {
- return preAppear(sceneRoot, existenceChange ? null : startValues.view,
- startVisibility, endValues.view, endVisibility);
- } else {
- return preDisappear(sceneRoot, startValues.view, startVisibility,
- existenceChange ? null : endValues.view, endVisibility);
+ return visInfo;
+ }
+
+ @Override
+ protected boolean setup(ViewGroup sceneRoot, TransitionValues startValues,
+ TransitionValues endValues) {
+ VisibilityInfo visInfo = getVisibilityChangeInfo(startValues, endValues);
+ // Ensure not in parent hierarchy that's also becoming visible/invisible
+ if (visInfo.visibilityChange) {
+ ViewGroup parent = (ViewGroup) ((visInfo.endParent != null) ?
+ visInfo.endParent : visInfo.startParent);
+ if (parent != null) {
+ if (!isHierarchyVisibilityChanging(sceneRoot, parent)) {
+ if (visInfo.fadeIn) {
+ return setupAppear(sceneRoot, startValues, visInfo.startVisibility,
+ endValues, visInfo.endVisibility);
+ } else {
+ return setupDisappear(sceneRoot, startValues, visInfo.startVisibility,
+ endValues, visInfo.endVisibility
+ );
+ }
+ }
}
- } else {
- return false;
}
+ return false;
}
@Override
protected Animator play(ViewGroup sceneRoot, TransitionValues startValues,
TransitionValues endValues) {
- boolean visibilityChange = false;
- boolean fadeIn = false;
- int startVisibility, endVisibility;
- View startParent, endParent;
- if (startValues != null) {
- startVisibility = (Integer) startValues.values.get(PROPNAME_VISIBILITY);
- startParent = (View) startValues.values.get(PROPNAME_PARENT);
- } else {
- startVisibility = -1;
- startParent = null;
- }
- if (endValues != null) {
- endVisibility = (Integer) endValues.values.get(PROPNAME_VISIBILITY);
- endParent = (View) endValues.values.get(PROPNAME_PARENT);
- } else {
- endVisibility = -1;
- endParent = null;
- }
- boolean existenceChange = false;
- if (startValues != null && endValues != null) {
- if (startVisibility == endVisibility && startParent == endParent) {
- return null;
+ VisibilityInfo visInfo = getVisibilityChangeInfo(startValues, endValues);
+ if (visInfo.visibilityChange) {
+ if (visInfo.fadeIn) {
+ return appear(sceneRoot, startValues, visInfo.startVisibility,
+ endValues, visInfo.endVisibility);
} else {
- if (startVisibility != endVisibility) {
- if (startVisibility == View.VISIBLE) {
- fadeIn = false;
- visibilityChange = true;
- } else if (endVisibility == View.VISIBLE) {
- fadeIn = true;
- visibilityChange = true;
- }
- // no visibilityChange if going between INVISIBLE and GONE
- } else if (startParent != endParent) {
- existenceChange = true;
- if (endParent == null) {
- fadeIn = false;
- visibilityChange = true;
- } else if (startParent == null) {
- fadeIn = true;
- visibilityChange = true;
- }
- }
- }
- }
- if (startValues == null) {
- existenceChange = true;
- fadeIn = true;
- visibilityChange = true;
- } else if (endValues == null) {
- existenceChange = true;
- fadeIn = false;
- visibilityChange = true;
- }
- if (visibilityChange) {
- if (fadeIn) {
- return appear(sceneRoot, existenceChange ? null : startValues.view, startVisibility,
- endValues.view, endVisibility);
- } else {
- return disappear(sceneRoot, startValues.view, startVisibility,
- existenceChange ? null : endValues.view, endVisibility);
+ return disappear(sceneRoot, startValues, visInfo.startVisibility,
+ endValues, visInfo.endVisibility);
}
}
return null;
@@ -187,14 +184,15 @@ public abstract class Visibility extends Transition {
* transition starting.
*
* @param sceneRoot
- * @param startView
+ * @param startValues
* @param startVisibility
- * @param endView
+ * @param endValues
* @param endVisibility
* @return
*/
- protected boolean preAppear(ViewGroup sceneRoot, View startView, int startVisibility,
- View endView, int endVisibility) {
+ protected boolean setupAppear(ViewGroup sceneRoot,
+ TransitionValues startValues, int startVisibility,
+ TransitionValues endValues, int endVisibility) {
return true;
}
@@ -202,15 +200,17 @@ public abstract class Visibility extends Transition {
* The default implementation of this method does nothing. Subclasses
* should override if they need to set up anything prior to the
* transition starting.
+ *
* @param sceneRoot
- * @param startView
+ * @param startValues
* @param startVisibility
- * @param endView
+ * @param endValues
* @param endVisibility
* @return
*/
- protected boolean preDisappear(ViewGroup sceneRoot, View startView, int startVisibility,
- View endView, int endVisibility) {
+ protected boolean setupDisappear(ViewGroup sceneRoot,
+ TransitionValues startValues, int startVisibility,
+ TransitionValues endValues, int endVisibility) {
return true;
}
@@ -219,25 +219,31 @@ public abstract class Visibility extends Transition {
* should override if they need to do anything when target objects
* appear during the scene change.
* @param sceneRoot
- * @param startView
+ * @param startValues
* @param startVisibility
- * @param endView
+ * @param endValues
* @param endVisibility
*/
- protected Animator appear(ViewGroup sceneRoot, View startView, int startVisibility,
- View endView, int endVisibility) { return null; }
+ 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 startView
+ * @param startValues
* @param startVisibility
- * @param endView
+ * @param endValues
* @param endVisibility
*/
- protected Animator disappear(ViewGroup sceneRoot, View startView, int startVisibility,
- View endView, int endVisibility) { return null; }
+ protected Animator disappear(ViewGroup sceneRoot,
+ TransitionValues startValues, int startVisibility,
+ TransitionValues endValues, int endVisibility) {
+ return null;
+ }
}
diff --git a/tests/TransitionTests/AndroidManifest.xml b/tests/TransitionTests/AndroidManifest.xml
index 98174ab34e6ce..3861164717f55 100644
--- a/tests/TransitionTests/AndroidManifest.xml
+++ b/tests/TransitionTests/AndroidManifest.xml
@@ -219,6 +219,13 @@
+
+
+
+
+
+
diff --git a/tests/TransitionTests/res/layout/fading_hierarchy.xml b/tests/TransitionTests/res/layout/fading_hierarchy.xml
new file mode 100644
index 0000000000000..a24a6b66b69fe
--- /dev/null
+++ b/tests/TransitionTests/res/layout/fading_hierarchy.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tests/TransitionTests/src/com/android/transitiontests/FadingHierarchy.java b/tests/TransitionTests/src/com/android/transitiontests/FadingHierarchy.java
new file mode 100644
index 0000000000000..e0fe379f1589f
--- /dev/null
+++ b/tests/TransitionTests/src/com/android/transitiontests/FadingHierarchy.java
@@ -0,0 +1,54 @@
+/*
+ * 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.Scene;
+import android.view.transition.TransitionManager;
+import android.widget.Button;
+
+public class FadingHierarchy extends Activity {
+
+ ViewGroup mRemovingContainer, mContainer;
+ Button mRemovingButton;
+ boolean mVisible = true;
+ ViewGroup mInnerContainerParent;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.fading_hierarchy);
+
+ mContainer = (ViewGroup) findViewById(R.id.container);
+ mRemovingContainer = (ViewGroup) findViewById(R.id.removingContainer);
+ mInnerContainerParent = (ViewGroup) mRemovingContainer.getParent();
+
+ mRemovingButton = (Button) findViewById(R.id.removingButton);
+ }
+
+ public void sendMessage(View view) {
+ TransitionManager.beginDelayedTransition(mContainer, null);
+ if (mVisible) {
+ mInnerContainerParent.removeView(mRemovingContainer);
+ } else {
+ mInnerContainerParent.addView(mRemovingContainer);
+ }
+ mVisible = !mVisible;
+ }
+}