summaryrefslogtreecommitdiffstats
path: root/core/java/android/transition/Transition.java
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android/transition/Transition.java')
-rw-r--r--core/java/android/transition/Transition.java162
1 files changed, 158 insertions, 4 deletions
diff --git a/core/java/android/transition/Transition.java b/core/java/android/transition/Transition.java
index c88b4c0..b7ae31e 100644
--- a/core/java/android/transition/Transition.java
+++ b/core/java/android/transition/Transition.java
@@ -19,10 +19,12 @@ package android.transition;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.TimeInterpolator;
+import android.graphics.Rect;
import android.util.ArrayMap;
import android.util.Log;
import android.util.LongSparseArray;
import android.util.SparseArray;
+import android.util.SparseLongArray;
import android.view.SurfaceView;
import android.view.TextureView;
import android.view.View;
@@ -60,10 +62,18 @@ import java.util.List;
* <p>Transitions can be declared in XML resource files inside the <code>res/transition</code>
* directory. Transition resources consist of a tag name for one of the Transition
* subclasses along with attributes to define some of the attributes of that transition.
- * For example, here is a minimal resource file that declares a {@link ChangeBounds} transition:</p>
+ * For example, here is a minimal resource file that declares a {@link ChangeBounds} transition:
*
* {@sample development/samples/ApiDemos/res/transition/changebounds.xml ChangeBounds}
*
+ * <p>{@link android.transition.Explode} transition:</p>
+ *
+ * {@sample development/samples/ApiDemos/res/transition/explode.xml Explode}
+ *
+ * <p>{@link android.transition.MoveImage} transition:</p>
+ *
+ * {@sample development/samples/ApiDemos/res/transition/move_image.xml MoveImage}
+ *
* <p>Note that attributes for the transition are not required, just as they are
* optional when declared in code; Transitions created from XML resources will use
* the same defaults as their code-created equivalents. Here is a slightly more
@@ -87,7 +97,8 @@ import java.util.List;
*
* Further information on XML resource descriptions for transitions can be found for
* {@link android.R.styleable#Transition}, {@link android.R.styleable#TransitionSet},
- * {@link android.R.styleable#TransitionTarget}, and {@link android.R.styleable#Fade}.
+ * {@link android.R.styleable#TransitionTarget}, {@link android.R.styleable#Fade}, and
+ * {@link android.R.styleable#Slide}.
*
*/
public abstract class Transition implements Cloneable {
@@ -149,6 +160,13 @@ public abstract class Transition implements Cloneable {
// to be run in runAnimators()
ArrayList<Animator> mAnimators = new ArrayList<Animator>();
+ // The function for calculating the Animation start delay.
+ TransitionPropagation mPropagation;
+
+ // The rectangular region for Transitions like Explode and TransitionPropagations
+ // like CircularPropagation
+ EpicenterCallback mEpicenterCallback;
+
/**
* Constructs a Transition object with no target objects. A transition with
* no targets defaults to running on all target objects in the scene hierarchy
@@ -435,6 +453,9 @@ public abstract class Transition implements Cloneable {
endValuesList.add(end);
}
ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators();
+ long minStartDelay = Long.MAX_VALUE;
+ int minAnimator = mAnimators.size();
+ SparseLongArray startDelays = new SparseLongArray();
for (int i = 0; i < startValuesList.size(); ++i) {
TransitionValues start = startValuesList.get(i);
TransitionValues end = endValuesList.get(i);
@@ -497,6 +518,12 @@ public abstract class Transition implements Cloneable {
view = (start != null) ? start.view : null;
}
if (animator != null) {
+ if (mPropagation != null) {
+ long delay = mPropagation
+ .getStartDelay(sceneRoot, this, start, end);
+ startDelays.put(mAnimators.size(), delay);
+ minStartDelay = Math.min(delay, minStartDelay);
+ }
AnimationInfo info = new AnimationInfo(view, getName(),
sceneRoot.getWindowId(), infoValues);
runningAnimators.put(animator, info);
@@ -506,6 +533,14 @@ public abstract class Transition implements Cloneable {
}
}
}
+ if (minStartDelay != 0) {
+ for (int i = 0; i < startDelays.size(); i++) {
+ int index = startDelays.keyAt(i);
+ Animator animator = mAnimators.get(index);
+ long delay = startDelays.valueAt(i) - minStartDelay + animator.getStartDelay();
+ animator.setStartDelay(delay);
+ }
+ }
}
/**
@@ -565,7 +600,7 @@ public abstract class Transition implements Cloneable {
/**
* This is called internally once all animations have been set up by the
- * transition hierarchy. \
+ * transition hierarchy.
*
* @hide
*/
@@ -1010,6 +1045,7 @@ public abstract class Transition implements Cloneable {
} else {
captureEndValues(values);
}
+ capturePropagationValues(values);
if (start) {
mStartValues.viewValues.put(view, values);
if (id >= 0) {
@@ -1035,6 +1071,7 @@ public abstract class Transition implements Cloneable {
} else {
captureEndValues(values);
}
+ capturePropagationValues(values);
if (start) {
mStartValues.viewValues.put(view, values);
} else {
@@ -1122,6 +1159,7 @@ public abstract class Transition implements Cloneable {
} else {
captureEndValues(values);
}
+ capturePropagationValues(values);
if (start) {
if (!isListViewItem) {
mStartValues.viewValues.put(view, values);
@@ -1340,7 +1378,7 @@ public abstract class Transition implements Cloneable {
animator.setDuration(getDuration());
}
if (getStartDelay() >= 0) {
- animator.setStartDelay(getStartDelay());
+ animator.setStartDelay(getStartDelay() + animator.getStartDelay());
}
if (getInterpolator() != null) {
animator.setInterpolator(getInterpolator());
@@ -1473,6 +1511,98 @@ public abstract class Transition implements Cloneable {
return this;
}
+ /**
+ * Sets the callback to use to find the epicenter of a Transition. A null value indicates
+ * that there is no epicenter in the Transition and getEpicenter() will return null.
+ * Transitions like {@link android.transition.Explode} use a point or Rect to orient
+ * the direction of travel. This is called the epicenter of the Transition and is
+ * typically centered on a touched View. The
+ * {@link android.transition.Transition.EpicenterCallback} allows a Transition to
+ * dynamically retrieve the epicenter during a Transition.
+ * @param epicenterCallback The callback to use to find the epicenter of the Transition.
+ */
+ public void setEpicenterCallback(EpicenterCallback epicenterCallback) {
+ mEpicenterCallback = epicenterCallback;
+ }
+
+ /**
+ * Returns the callback used to find the epicenter of the Transition.
+ * Transitions like {@link android.transition.Explode} use a point or Rect to orient
+ * the direction of travel. This is called the epicenter of the Transition and is
+ * typically centered on a touched View. The
+ * {@link android.transition.Transition.EpicenterCallback} allows a Transition to
+ * dynamically retrieve the epicenter during a Transition.
+ * @return the callback used to find the epicenter of the Transition.
+ */
+ public EpicenterCallback getEpicenterCallback() {
+ return mEpicenterCallback;
+ }
+
+ /**
+ * Returns the epicenter as specified by the
+ * {@link android.transition.Transition.EpicenterCallback} or null if no callback exists.
+ * @return the epicenter as specified by the
+ * {@link android.transition.Transition.EpicenterCallback} or null if no callback exists.
+ * @see #setEpicenterCallback(android.transition.Transition.EpicenterCallback)
+ */
+ public Rect getEpicenter() {
+ if (mEpicenterCallback == null) {
+ return null;
+ }
+ return mEpicenterCallback.getEpicenter(this);
+ }
+
+ /**
+ * Sets the method for determining Animator start delays.
+ * When a Transition affects several Views like {@link android.transition.Explode} or
+ * {@link android.transition.Slide}, there may be a desire to have a "wave-front" effect
+ * such that the Animator start delay depends on position of the View. The
+ * TransitionPropagation specifies how the start delays are calculated.
+ * @param transitionPropagation The class used to determine the start delay of
+ * Animators created by this Transition. A null value
+ * indicates that no delay should be used.
+ */
+ public void setPropagation(TransitionPropagation transitionPropagation) {
+ mPropagation = transitionPropagation;
+ }
+
+ /**
+ * Returns the {@link android.transition.TransitionPropagation} used to calculate Animator start
+ * delays.
+ * When a Transition affects several Views like {@link android.transition.Explode} or
+ * {@link android.transition.Slide}, there may be a desire to have a "wave-front" effect
+ * such that the Animator start delay depends on position of the View. The
+ * TransitionPropagation specifies how the start delays are calculated.
+ * @return the {@link android.transition.TransitionPropagation} used to calculate Animator start
+ * delays. This is null by default.
+ */
+ public TransitionPropagation getPropagation() {
+ return mPropagation;
+ }
+
+ /**
+ * Captures TransitionPropagation values for the given view and the
+ * hierarchy underneath it.
+ */
+ void capturePropagationValues(TransitionValues transitionValues) {
+ if (mPropagation != null) {
+ String[] propertyNames = mPropagation.getPropagationProperties();
+ if (propertyNames == null) {
+ return;
+ }
+ boolean containsAll = true;
+ for (int i = 0; i < propertyNames.length; i++) {
+ if (!transitionValues.values.containsKey(propertyNames[i])) {
+ containsAll = false;
+ break;
+ }
+ }
+ if (!containsAll) {
+ mPropagation.captureValues(transitionValues);
+ }
+ }
+ }
+
Transition setSceneRoot(ViewGroup sceneRoot) {
mSceneRoot = sceneRoot;
return this;
@@ -1710,4 +1840,28 @@ public abstract class Transition implements Cloneable {
}
}
+ /**
+ * Class to get the epicenter of Transition. Use
+ * {@link #setEpicenterCallback(android.transition.Transition.EpicenterCallback)} to
+ * set the callback used to calculate the epicenter of the Transition. Override
+ * {@link #getEpicenter()} to return the rectangular region in screen coordinates of
+ * the epicenter of the transition.
+ * @see #setEpicenterCallback(android.transition.Transition.EpicenterCallback)
+ */
+ public static abstract class EpicenterCallback {
+
+ /**
+ * Implementers must override to return the epicenter of the Transition in screen
+ * coordinates. Transitions like {@link android.transition.Explode} depend upon
+ * an epicenter for the Transition. In Explode, Views move toward or away from the
+ * center of the epicenter Rect along the vector between the epicenter and the center
+ * of the View appearing and disappearing. Some Transitions, such as
+ * {@link android.transition.Fade} pay no attention to the epicenter.
+ *
+ * @param transition The transition for which the epicenter applies.
+ * @return The Rect region of the epicenter of <code>transition</code> or null if
+ * there is no epicenter.
+ */
+ public abstract Rect getEpicenter(Transition transition);
+ }
}