import android.animation.AnimatorListenerAdapter;
import android.animation.TimeInterpolator;
import android.util.ArrayMap;
+import android.util.Log;
import android.util.LongSparseArray;
import android.util.Pair;
import android.util.SparseArray;
int mNumInstances = 0;
- /**
- * The set of listeners to be sent transition lifecycle events.
- */
+
+ // The set of listeners to be sent transition lifecycle events.
ArrayList<TransitionListener> mListeners = null;
+ // The set of animators collected from calls to play(), to be run in runAnimations()
+ ArrayMap<Pair<TransitionValues, TransitionValues>, Animator> mAnimatorMap =
+ new ArrayMap<Pair<TransitionValues, TransitionValues>, Animator>();
+
/**
* Constructs a Transition object with no target objects. A transition with
* no targets defaults to running on all target objects in the scene hierarchy
*/
protected void play(ViewGroup sceneRoot, TransitionValuesMaps startValues,
TransitionValuesMaps endValues) {
+ if (DBG) {
+ Log.d(LOG_TAG, "play() for " + this);
+ }
mPlayStartValuesList.clear();
mPlayEndValuesList.clear();
ArrayMap<View, TransitionValues> endCopy =
for (int i = 0; i < startValuesList.size(); ++i) {
TransitionValues start = startValuesList.get(i);
TransitionValues end = endValuesList.get(i);
- // TODO: what to do about targetIds and itemIds?
- 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);
+ // Only bother trying to animate with values that differ between start/end
+ if (start != null || end != null) {
+ if (start == null || !start.equals(end)) {
+ if (DBG) {
+ View view = (end != null) ? end.view : start.view;
+ Log.d(LOG_TAG, " differing start/end values for view " +
+ view);
+ if (start == null || end == null) {
+ if (start == null) {
+ Log.d(LOG_TAG, " " + ((start == null) ?
+ "start null, end non-null" : "start non-null, end null"));
+ }
+ } else {
+ for (String key : start.values.keySet()) {
+ Object startValue = start.values.get(key);
+ Object endValue = end.values.get(key);
+ if (startValue != endValue && !startValue.equals(endValue)) {
+ Log.d(LOG_TAG, " " + key + ": start(" + startValue +
+ "), end(" + endValue +")");
+ }
+ }
+ }
+ }
+ // TODO: what to do about targetIds and itemIds?
+ 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);
+ }
+ } else if (DBG) {
+ View view = (end != null) ? end.view : start.view;
+ Log.d(LOG_TAG, " No change for view " + view);
+ }
}
}
}
- 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
* @hide
*/
protected void runAnimations() {
-
+ if (DBG && mPlayStartValuesList.size() > 0) {
+ Log.d(LOG_TAG, "runAnimations (" + mPlayStartValuesList.size() + ") on " + this);
+ }
startTransition();
// Now walk the list of TransitionValues, calling play for each pair
for (int i = 0; i < mPlayStartValuesList.size(); ++i) {
TransitionValues start = mPlayStartValuesList.get(i);
TransitionValues end = mPlayEndValuesList.get(i);
+ Animator anim = mAnimatorMap.get(new Pair(start, end));
+ if (DBG) {
+ Log.d(LOG_TAG, " anim: " + anim);
+ }
startTransition();
- runAnimator(mAnimatorMap.get(new Pair(start, end)));
+ runAnimator(anim);
}
mPlayStartValuesList.clear();
mPlayEndValuesList.clear();
String toString(String indent) {
String result = indent + getClass().getSimpleName() + "@" +
Integer.toHexString(hashCode()) + ": ";
- result += "dur(" + mDuration + ") ";
- result += "dly(" + mStartDelay + ") ";
- result += "interp(" + mInterpolator + ") ";
- result += "tgts(";
- if (mTargetIds != null) {
- for (int i = 0; i < mTargetIds.length; ++i) {
- if (i > 0) {
- result += ", ";
+ if (mDuration != -1) {
+ result += "dur(" + mDuration + ") ";
+ }
+ if (mStartDelay != -1) {
+ result += "dly(" + mStartDelay + ") ";
+ }
+ if (mInterpolator != null) {
+ result += "interp(" + mInterpolator + ") ";
+ }
+ if (mTargetIds != null || mTargets != null) {
+ result += "tgts(";
+ if (mTargetIds != null) {
+ for (int i = 0; i < mTargetIds.length; ++i) {
+ if (i > 0) {
+ result += ", ";
+ }
+ result += mTargetIds[i];
}
- result += mTargetIds[i];
}
- }
- if (mTargets != null) {
- for (int i = 0; i < mTargets.length; ++i) {
- if (i > 0) {
- result += ", ";
+ if (mTargets != null) {
+ for (int i = 0; i < mTargets.length; ++i) {
+ if (i > 0) {
+ result += ", ";
+ }
+ result += mTargets[i];
}
- result += mTargets[i];
}
+ result += ")";
}
- result += ")";
return result;
}
package android.view.transition;
import android.util.ArrayMap;
+import android.util.Log;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
public class TransitionManager {
// TODO: how to handle enter/exit?
+ private static String LOG_TAG = "TransitionManager";
+
private static final Transition sDefaultTransition = new AutoTransition();
private Transition mDefaultTransition = new AutoTransition();
observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
public boolean onPreDraw() {
sceneRoot.getViewTreeObserver().removeOnPreDrawListener(this);
+ sPendingTransitions.remove(sceneRoot);
// Add to running list, handle end to remove it
sRunningTransitions.put(sceneRoot, transition);
transition.addListener(new Transition.TransitionListenerAdapter() {
* value of null causes the TransitionManager to use the default transition.
*/
public static void beginDelayedTransition(final ViewGroup sceneRoot, Transition transition) {
-
- if (!sPendingTransitions.contains(sceneRoot)) {
+ if (!sPendingTransitions.contains(sceneRoot) && sceneRoot.hasLayout()) {
+ if (Transition.DBG) {
+ Log.d(LOG_TAG, "beginDelayedTransition: root, transition = " +
+ sceneRoot + ", " + transition);
+ }
sPendingTransitions.add(sceneRoot);
if (transition == null) {
transition = sDefaultTransition;
final Transition finalTransition = transition.clone();
sceneChangeSetup(sceneRoot, transition);
sceneRoot.setCurrentScene(null);
- sceneRoot.postOnAnimation(new Runnable() {
- @Override
- public void run() {
- sPendingTransitions.remove(sceneRoot);
- sceneChangeRunTransition(sceneRoot, finalTransition);
- }
- });
+ sceneChangeRunTransition(sceneRoot, finalTransition);
}
}
}