Add exclude() methods to Transition

It would be useful for a transition to declare not just which
targets it wants to be run on, but also which targets it wants
to avoid. For example, you may not want to animate the items of
a ListView, or some other specific target in the view hierarchy.

This change adds various exclude*() methods which make it
possible to alter a transition to automatically ignore specific
views, ids, or classes in the hierarchy.

Issue #10692794 Transitions: Need API for excluding targets

Change-Id: If38025cdbee537a545e5a4268cbbd763af4622c5
diff --git a/api/current.txt b/api/current.txt
index b5930ec..abb86cd 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -25507,12 +25507,18 @@
   public abstract class Transition implements java.lang.Cloneable {
     ctor public Transition();
     method public android.transition.Transition addListener(android.transition.Transition.TransitionListener);
+    method public android.transition.Transition addTarget(int);
     method public android.transition.Transition addTarget(android.view.View);
-    method public android.transition.Transition addTargetId(int);
     method public abstract void captureEndValues(android.transition.TransitionValues);
     method public abstract void captureStartValues(android.transition.TransitionValues);
     method public android.transition.Transition clone();
     method public android.animation.Animator createAnimator(android.view.ViewGroup, android.transition.TransitionValues, android.transition.TransitionValues);
+    method public android.transition.Transition excludeChildren(int, boolean);
+    method public android.transition.Transition excludeChildren(android.view.View, boolean);
+    method public android.transition.Transition excludeChildren(java.lang.Class, boolean);
+    method public android.transition.Transition excludeTarget(int, boolean);
+    method public android.transition.Transition excludeTarget(android.view.View, boolean);
+    method public android.transition.Transition excludeTarget(java.lang.Class, boolean);
     method public long getDuration();
     method public android.animation.TimeInterpolator getInterpolator();
     method public java.lang.String getName();
@@ -25522,8 +25528,8 @@
     method public java.lang.String[] getTransitionProperties();
     method public android.transition.TransitionValues getTransitionValues(android.view.View, boolean);
     method public android.transition.Transition removeListener(android.transition.Transition.TransitionListener);
+    method public android.transition.Transition removeTarget(int);
     method public android.transition.Transition removeTarget(android.view.View);
-    method public android.transition.Transition removeTargetId(int);
     method public android.transition.Transition setDuration(long);
     method public android.transition.Transition setInterpolator(android.animation.TimeInterpolator);
     method public android.transition.Transition setStartDelay(long);
diff --git a/core/java/android/transition/Transition.java b/core/java/android/transition/Transition.java
index 8ea9d48..c588c6b 100644
--- a/core/java/android/transition/Transition.java
+++ b/core/java/android/transition/Transition.java
@@ -29,6 +29,7 @@
 import android.view.ViewGroup;
 import android.view.ViewOverlay;
 import android.widget.ListView;
+import android.widget.Spinner;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -100,6 +101,12 @@
     TimeInterpolator mInterpolator = null;
     ArrayList<Integer> mTargetIds = new ArrayList<Integer>();
     ArrayList<View> mTargets = new ArrayList<View>();
+    ArrayList<Integer> mTargetIdExcludes = null;
+    ArrayList<View> mTargetExcludes = null;
+    ArrayList<Class> mTargetTypeExcludes = null;
+    ArrayList<Integer> mTargetIdChildExcludes = null;
+    ArrayList<View> mTargetChildExcludes = null;
+    ArrayList<Class> mTargetTypeChildExcludes = null;
     private TransitionValuesMaps mStartValues = new TransitionValuesMaps();
     private TransitionValuesMaps mEndValues = new TransitionValuesMaps();
     TransitionSet mParent = null;
@@ -430,10 +437,8 @@
                         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"));
-                            }
+                            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);
@@ -504,6 +509,21 @@
      * views are ignored and only the ids are used).
      */
     boolean isValidTarget(View target, long targetId) {
+        if (mTargetIdExcludes != null && mTargetIdExcludes.contains(targetId)) {
+            return false;
+        }
+        if (mTargetExcludes != null && mTargetExcludes.contains(target)) {
+            return false;
+        }
+        if (mTargetTypeExcludes != null && target != null) {
+            int numTypes = mTargetTypeExcludes.size();
+            for (int i = 0; i < numTypes; ++i) {
+                Class type = mTargetTypeExcludes.get(i);
+                if (type.isInstance(target)) {
+                    return false;
+                }
+            }
+        }
         if (mTargetIds.size() == 0 && mTargets.size() == 0) {
             return true;
         }
@@ -652,9 +672,9 @@
      * @return The Transition to which the targetId is added.
      * Returning the same object makes it easier to chain calls during
      * construction, such as
-     * <code>transitionSet.addTransitions(new Fade()).addTargetId(someId);</code>
+     * <code>transitionSet.addTransitions(new Fade()).addTarget(someId);</code>
      */
-    public Transition addTargetId(int targetId) {
+    public Transition addTarget(int targetId) {
         if (targetId > 0) {
             mTargetIds.add(targetId);
         }
@@ -671,7 +691,7 @@
      * construction, such as
      * <code>transitionSet.addTransitions(new Fade()).removeTargetId(someId);</code>
      */
-    public Transition removeTargetId(int targetId) {
+    public Transition removeTarget(int targetId) {
         if (targetId > 0) {
             mTargetIds.remove(targetId);
         }
@@ -679,6 +699,212 @@
     }
 
     /**
+     * Whether to add the given id to the list of target ids to exclude from this
+     * transition. The <code>exclude</code> parameter specifies whether the target
+     * should be added to or removed from the excluded list.
+     *
+     * <p>Excluding targets is a general mechanism for allowing transitions to run on
+     * a view hierarchy while skipping target views that should not be part of
+     * the transition. For example, you may want to avoid animating children
+     * of a specific ListView or Spinner. Views can be excluded either by their
+     * id, or by their instance reference, or by the Class of that view
+     * (eg, {@link Spinner}).</p>
+     *
+     * @see #excludeChildren(int, boolean)
+     * @see #excludeTarget(View, boolean)
+     * @see #excludeTarget(Class, boolean)
+     *
+     * @param targetId The id of a target to ignore when running this transition.
+     * @param exclude Whether to add the target to or remove the target from the
+     * current list of excluded targets.
+     * @return This transition object.
+     */
+    public Transition excludeTarget(int targetId, boolean exclude) {
+        mTargetIdExcludes = excludeId(mTargetIdExcludes, targetId, exclude);
+        return this;
+    }
+
+    /**
+     * Whether to add the children of the given id to the list of targets to exclude
+     * from this transition. The <code>exclude</code> parameter specifies whether
+     * the children of the target should be added to or removed from the excluded list.
+     * Excluding children in this way provides a simple mechanism for excluding all
+     * children of specific targets, rather than individually excluding each
+     * child individually.
+     *
+     * <p>Excluding targets is a general mechanism for allowing transitions to run on
+     * a view hierarchy while skipping target views that should not be part of
+     * the transition. For example, you may want to avoid animating children
+     * of a specific ListView or Spinner. Views can be excluded either by their
+     * id, or by their instance reference, or by the Class of that view
+     * (eg, {@link Spinner}).</p>
+     *
+     * @see #excludeTarget(int, boolean)
+     * @see #excludeChildren(View, boolean)
+     * @see #excludeChildren(Class, boolean)
+     *
+     * @param targetId The id of a target whose children should be ignored when running
+     * this transition.
+     * @param exclude Whether to add the target to or remove the target from the
+     * current list of excluded-child targets.
+     * @return This transition object.
+     */
+    public Transition excludeChildren(int targetId, boolean exclude) {
+        mTargetIdChildExcludes = excludeId(mTargetIdChildExcludes, targetId, exclude);
+        return this;
+    }
+
+    /**
+     * Utility method to manage the boilerplate code that is the same whether we
+     * are excluding targets or their children.
+     */
+    private ArrayList<Integer> excludeId(ArrayList<Integer> list, int targetId, boolean exclude) {
+        if (targetId > 0) {
+            if (exclude) {
+                list = ArrayListManager.add(list, targetId);
+            } else {
+                list = ArrayListManager.remove(list, targetId);
+            }
+        }
+        return list;
+    }
+
+    /**
+     * Whether to add the given target to the list of targets to exclude from this
+     * transition. The <code>exclude</code> parameter specifies whether the target
+     * should be added to or removed from the excluded list.
+     *
+     * <p>Excluding targets is a general mechanism for allowing transitions to run on
+     * a view hierarchy while skipping target views that should not be part of
+     * the transition. For example, you may want to avoid animating children
+     * of a specific ListView or Spinner. Views can be excluded either by their
+     * id, or by their instance reference, or by the Class of that view
+     * (eg, {@link Spinner}).</p>
+     *
+     * @see #excludeChildren(View, boolean)
+     * @see #excludeTarget(int, boolean)
+     * @see #excludeTarget(Class, boolean)
+     *
+     * @param target The target to ignore when running this transition.
+     * @param exclude Whether to add the target to or remove the target from the
+     * current list of excluded targets.
+     * @return This transition object.
+     */
+    public Transition excludeTarget(View target, boolean exclude) {
+        mTargetExcludes = excludeView(mTargetExcludes, target, exclude);
+        return this;
+    }
+
+    /**
+     * Whether to add the children of given target to the list of target children
+     * to exclude from this transition. The <code>exclude</code> parameter specifies
+     * whether the target should be added to or removed from the excluded list.
+     *
+     * <p>Excluding targets is a general mechanism for allowing transitions to run on
+     * a view hierarchy while skipping target views that should not be part of
+     * the transition. For example, you may want to avoid animating children
+     * of a specific ListView or Spinner. Views can be excluded either by their
+     * id, or by their instance reference, or by the Class of that view
+     * (eg, {@link Spinner}).</p>
+     *
+     * @see #excludeTarget(View, boolean)
+     * @see #excludeChildren(int, boolean)
+     * @see #excludeChildren(Class, boolean)
+     *
+     * @param target The target to ignore when running this transition.
+     * @param exclude Whether to add the target to or remove the target from the
+     * current list of excluded targets.
+     * @return This transition object.
+     */
+    public Transition excludeChildren(View target, boolean exclude) {
+        mTargetChildExcludes = excludeView(mTargetChildExcludes, target, exclude);
+        return this;
+    }
+
+    /**
+     * Utility method to manage the boilerplate code that is the same whether we
+     * are excluding targets or their children.
+     */
+    private ArrayList<View> excludeView(ArrayList<View> list, View target, boolean exclude) {
+        if (target != null) {
+            if (exclude) {
+                list = ArrayListManager.add(list, target);
+            } else {
+                list = ArrayListManager.remove(list, target);
+            }
+        }
+        return list;
+    }
+
+    /**
+     * Whether to add the given type to the list of types to exclude from this
+     * transition. The <code>exclude</code> parameter specifies whether the target
+     * type should be added to or removed from the excluded list.
+     *
+     * <p>Excluding targets is a general mechanism for allowing transitions to run on
+     * a view hierarchy while skipping target views that should not be part of
+     * the transition. For example, you may want to avoid animating children
+     * of a specific ListView or Spinner. Views can be excluded either by their
+     * id, or by their instance reference, or by the Class of that view
+     * (eg, {@link Spinner}).</p>
+     *
+     * @see #excludeChildren(Class, boolean)
+     * @see #excludeTarget(int, boolean)
+     * @see #excludeTarget(View, boolean)
+     *
+     * @param type The type to ignore when running this transition.
+     * @param exclude Whether to add the target type to or remove it from the
+     * current list of excluded target types.
+     * @return This transition object.
+     */
+    public Transition excludeTarget(Class type, boolean exclude) {
+        mTargetTypeExcludes = excludeType(mTargetTypeExcludes, type, exclude);
+        return this;
+    }
+
+    /**
+     * Whether to add the given type to the list of types whose children should
+     * be excluded from this transition. The <code>exclude</code> parameter
+     * specifies whether the target type should be added to or removed from
+     * the excluded list.
+     *
+     * <p>Excluding targets is a general mechanism for allowing transitions to run on
+     * a view hierarchy while skipping target views that should not be part of
+     * the transition. For example, you may want to avoid animating children
+     * of a specific ListView or Spinner. Views can be excluded either by their
+     * id, or by their instance reference, or by the Class of that view
+     * (eg, {@link Spinner}).</p>
+     *
+     * @see #excludeTarget(Class, boolean)
+     * @see #excludeChildren(int, boolean)
+     * @see #excludeChildren(View, boolean)
+     *
+     * @param type The type to ignore when running this transition.
+     * @param exclude Whether to add the target type to or remove it from the
+     * current list of excluded target types.
+     * @return This transition object.
+     */
+    public Transition excludeChildren(Class type, boolean exclude) {
+        mTargetTypeChildExcludes = excludeType(mTargetTypeChildExcludes, type, exclude);
+        return this;
+    }
+
+    /**
+     * Utility method to manage the boilerplate code that is the same whether we
+     * are excluding targets or their children.
+     */
+    private ArrayList<Class> excludeType(ArrayList<Class> list, Class type, boolean exclude) {
+        if (type != null) {
+            if (exclude) {
+                list = ArrayListManager.add(list, type);
+            } else {
+                list = ArrayListManager.remove(list, type);
+            }
+        }
+        return list;
+    }
+
+    /**
      * Sets the target view instances that this Transition is interested in
      * animating. By default, there are no targets, and a Transition will
      * listen for changes on every view in the hierarchy below the sceneRoot
@@ -686,18 +912,18 @@
      * the Transition to only listen for, and act on, these views.
      * All other views will be ignored.
      *
-     * <p>The target list is like the {@link #addTargetId(int) targetId}
+     * <p>The target list is like the {@link #addTarget(int) targetId}
      * list except this list specifies the actual View instances, not the ids
      * of the views. This is an important distinction when scene changes involve
      * view hierarchies which have been inflated separately; different views may
      * share the same id but not actually be the same instance. If the transition
-     * should treat those views as the same, then {@link #addTargetId(int)} should be used
+     * should treat those views as the same, then {@link #addTarget(int)} should be used
      * instead of {@link #addTarget(View)}. If, on the other hand, scene changes involve
      * changes all within the same view hierarchy, among views which do not
      * necessarily have ids set on them, then the target list of views may be more
      * convenient.</p>
      *
-     * @see #addTargetId(int)
+     * @see #addTarget(int)
      * @param target A View on which the Transition will act, must be non-null.
      * @return The Transition to which the target is added.
      * Returning the same object makes it easier to chain calls during
@@ -842,15 +1068,30 @@
             // ignore listview children unless we can track them with stable IDs
             return;
         }
-        long id;
+        int id = View.NO_ID;
+        long itemId = View.NO_ID;
         if (!isListViewItem) {
             id = view.getId();
         } else {
             ListView listview = (ListView) view.getParent();
             int position = listview.getPositionForView(view);
-            id = listview.getItemIdAtPosition(position);
+            itemId = listview.getItemIdAtPosition(position);
             view.setHasTransientState(true);
         }
+        if (mTargetIdExcludes != null && mTargetIdExcludes.contains(id)) {
+            return;
+        }
+        if (mTargetExcludes != null && mTargetExcludes.contains(view)) {
+            return;
+        }
+        if (mTargetTypeExcludes != null && view != null) {
+            int numTypes = mTargetTypeExcludes.size();
+            for (int i = 0; i < numTypes; ++i) {
+                if (mTargetTypeExcludes.get(i).isInstance(view)) {
+                    return;
+                }
+            }
+        }
         TransitionValues values = new TransitionValues();
         values.view = view;
         captureStartValues(values);
@@ -861,7 +1102,7 @@
                     mStartValues.idValues.put((int) id, values);
                 }
             } else {
-                mStartValues.itemIdValues.put(id, values);
+                mStartValues.itemIdValues.put(itemId, values);
             }
         } else {
             if (!isListViewItem) {
@@ -870,10 +1111,25 @@
                     mEndValues.idValues.put((int) id, values);
                 }
             } else {
-                mEndValues.itemIdValues.put(id, values);
+                mEndValues.itemIdValues.put(itemId, values);
             }
         }
         if (view instanceof ViewGroup) {
+            // Don't traverse child hierarchy if there are any child-excludes on this view
+            if (mTargetIdChildExcludes != null && mTargetIdChildExcludes.contains(id)) {
+                return;
+            }
+            if (mTargetChildExcludes != null && mTargetChildExcludes.contains(view)) {
+                return;
+            }
+            if (mTargetTypeChildExcludes != null && view != null) {
+                int numTypes = mTargetTypeChildExcludes.size();
+                for (int i = 0; i < numTypes; ++i) {
+                    if (mTargetTypeChildExcludes.get(i).isInstance(view)) {
+                        return;
+                    }
+                }
+            }
             ViewGroup parent = (ViewGroup) view;
             for (int i = 0; i < parent.getChildCount(); ++i) {
                 captureHierarchy(parent.getChildAt(i), start);
@@ -1356,4 +1612,51 @@
             this.values = values;
         }
     }
+
+    /**
+     * Utility class for managing typed ArrayLists efficiently. In particular, this
+     * can be useful for lists that we don't expect to be used often (eg, the exclude
+     * lists), so we'd like to keep them nulled out by default. This causes the code to
+     * become tedious, with constant null checks, code to allocate when necessary,
+     * and code to null out the reference when the list is empty. This class encapsulates
+     * all of that functionality into simple add()/remove() methods which perform the
+     * necessary checks, allocation/null-out as appropriate, and return the
+     * resulting list.
+     */
+    private static class ArrayListManager {
+
+        /**
+         * Add the specified item to the list, returning the resulting list.
+         * The returned list can either the be same list passed in or, if that
+         * list was null, the new list that was created.
+         *
+         * Note that the list holds unique items; if the item already exists in the
+         * list, the list is not modified.
+         */
+        static <T> ArrayList<T> add(ArrayList<T> list, T item) {
+            if (list == null) {
+                list = new ArrayList<T>();
+            }
+            if (!list.contains(item)) {
+                list.add(item);
+            }
+            return list;
+        }
+
+        /**
+         * Remove the specified item from the list, returning the resulting list.
+         * The returned list can either the be same list passed in or, if that
+         * list becomes empty as a result of the remove(), the new list was created.
+         */
+        static <T> ArrayList<T> remove(ArrayList<T> list, T item) {
+            if (list != null) {
+                list.remove(item);
+                if (list.isEmpty()) {
+                    list = null;
+                }
+            }
+            return list;
+        }
+    }
+
 }
diff --git a/core/java/android/transition/TransitionInflater.java b/core/java/android/transition/TransitionInflater.java
index ebedeeb..eeb6cba 100644
--- a/core/java/android/transition/TransitionInflater.java
+++ b/core/java/android/transition/TransitionInflater.java
@@ -235,7 +235,7 @@
         int numTargets = targetIds.size();
         if (numTargets > 0) {
             for (int i = 0; i < numTargets; ++i) {
-                transition.addTargetId(targetIds.get(i));
+                transition.addTarget(targetIds.get(i));
             }
         }
     }
diff --git a/core/java/android/transition/TransitionSet.java b/core/java/android/transition/TransitionSet.java
index 1972c2a..f72b36e 100644
--- a/core/java/android/transition/TransitionSet.java
+++ b/core/java/android/transition/TransitionSet.java
@@ -155,8 +155,8 @@
     }
 
     @Override
-    public TransitionSet addTargetId(int targetId) {
-        return (TransitionSet) super.addTargetId(targetId);
+    public TransitionSet addTarget(int targetId) {
+        return (TransitionSet) super.addTarget(targetId);
     }
 
     @Override
@@ -165,8 +165,8 @@
     }
 
     @Override
-    public TransitionSet removeTargetId(int targetId) {
-        return (TransitionSet) super.removeTargetId(targetId);
+    public TransitionSet removeTarget(int targetId) {
+        return (TransitionSet) super.removeTarget(targetId);
     }
 
     @Override
@@ -278,9 +278,11 @@
     @Override
     public void captureStartValues(TransitionValues transitionValues) {
         int targetId = transitionValues.view.getId();
-        for (Transition childTransition : mTransitions) {
-            if (childTransition.isValidTarget(transitionValues.view, targetId)) {
-                childTransition.captureStartValues(transitionValues);
+        if (isValidTarget(transitionValues.view, targetId)) {
+            for (Transition childTransition : mTransitions) {
+                if (childTransition.isValidTarget(transitionValues.view, targetId)) {
+                    childTransition.captureStartValues(transitionValues);
+                }
             }
         }
     }
@@ -288,9 +290,11 @@
     @Override
     public void captureEndValues(TransitionValues transitionValues) {
         int targetId = transitionValues.view.getId();
-        for (Transition childTransition : mTransitions) {
-            if (childTransition.isValidTarget(transitionValues.view, targetId)) {
-                childTransition.captureEndValues(transitionValues);
+        if (isValidTarget(transitionValues.view, targetId)) {
+            for (Transition childTransition : mTransitions) {
+                if (childTransition.isValidTarget(transitionValues.view, targetId)) {
+                    childTransition.captureEndValues(transitionValues);
+                }
             }
         }
     }
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 7ddf2e9..4a26a05 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -4544,7 +4544,7 @@
     </declare-styleable>
 
     <!-- Use <code>target</code> as the root tag of the XML resource that
-     describes a {@link android.transition.Transition#addTargetId(int)
+     describes a {@link android.transition.Transition#addTarget(int)
      targetId} of a transition. There can be one or more targets inside
      a <code>targets</code> tag, which is itself inside an appropriate
      {@link android.R.styleable#Transition Transition} tag.
diff --git a/tests/TransitionTests/src/com/android/transitiontests/ContactsExpansion.java b/tests/TransitionTests/src/com/android/transitiontests/ContactsExpansion.java
index 482dc05..f687da3 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/ContactsExpansion.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/ContactsExpansion.java
@@ -76,10 +76,10 @@
 
         final TransitionSet myTransition = new TransitionSet();
         myTransition.addTransition(new Fade(Fade.IN)).
-                addTransition(new Rotate().addTargetId(R.id.contact_arrow)).
+                addTransition(new Rotate().addTarget(R.id.contact_arrow)).
                 addTransition(new ChangeBounds()).
                 addTransition(new Fade(Fade.OUT)).
-                addTransition(new Crossfade().addTargetId(R.id.contact_picture));
+                addTransition(new Crossfade().addTarget(R.id.contact_picture));
         final ToggleScene toggleScene = new ToggleScene(container, myTransition);
         contactItem.setOnClickListener(new View.OnClickListener() {
             @Override
diff --git a/tests/TransitionTests/src/com/android/transitiontests/CrossFadeDemo.java b/tests/TransitionTests/src/com/android/transitiontests/CrossFadeDemo.java
index eb799ec..5bb0e77 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/CrossFadeDemo.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/CrossFadeDemo.java
@@ -47,8 +47,8 @@
         Crossfade crossfade = new Crossfade();
         crossfade.setFadeBehavior(Crossfade.FADE_BEHAVIOR_CROSSFADE);
         crossfade.setResizeBehavior(Crossfade.RESIZE_BEHAVIOR_NONE);
-        crossfade.addTargetId(R.id.textview).addTargetId(R.id.textview1).
-                addTargetId(R.id.textview2);
+        crossfade.addTarget(R.id.textview).addTarget(R.id.textview1).
+                addTarget(R.id.textview2);
         mTransitionManager = new TransitionManager();
         TransitionSet moveCrossFade = new TransitionSet();
         moveCrossFade.addTransition(crossfade).addTransition(new ChangeBounds());
diff --git a/tests/TransitionTests/src/com/android/transitiontests/CrossfadeImage.java b/tests/TransitionTests/src/com/android/transitiontests/CrossfadeImage.java
index 09b495f..1f278b9 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/CrossfadeImage.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/CrossfadeImage.java
@@ -48,7 +48,7 @@
         mImageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
 
         Crossfade mCrossfade = new Crossfade();
-        mCrossfade.addTargetId(R.id.contact_picture);
+        mCrossfade.addTarget(R.id.contact_picture);
 
         TransitionSet group = new TransitionSet();
         group.setDuration(1500);
diff --git a/tests/TransitionTests/src/com/android/transitiontests/CrossfadeMultiple.java b/tests/TransitionTests/src/com/android/transitiontests/CrossfadeMultiple.java
index c1183987..d784f75 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/CrossfadeMultiple.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/CrossfadeMultiple.java
@@ -57,7 +57,7 @@
         mTextView = (TextView) findViewById(R.id.textview);
 
         mCrossfade = new Crossfade();
-        mCrossfade.addTargetId(R.id.button).addTargetId(R.id.textview).addTargetId(R.id.imageview);
+        mCrossfade.addTarget(R.id.button).addTarget(R.id.textview).addTarget(R.id.imageview);
 
         mCrossfadeGroup = new TransitionSet();
         mCrossfadeGroup.setDuration(300);
diff --git a/tests/TransitionTests/src/com/android/transitiontests/Demo1.java b/tests/TransitionTests/src/com/android/transitiontests/Demo1.java
index 5c0cd45..5b5eb15 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/Demo1.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/Demo1.java
@@ -70,9 +70,9 @@
         if (mFirstTime) {
             mFirstTime = false;
             TransitionSet transition = new TransitionSet();
-            transition.addTransition(new Fade().addTargetId(R.id.resultsText).
-                    addTargetId(R.id.resultsList)).
-                    addTransition(new ChangeBounds().addTargetId(R.id.searchContainer));
+            transition.addTransition(new Fade().addTarget(R.id.resultsText).
+                    addTarget(R.id.resultsList)).
+                    addTransition(new ChangeBounds().addTarget(R.id.searchContainer));
             mTransitionManager = new TransitionManager();
             mTransitionManager.setTransition(mSearchScreen, transition);
             mTransitionManager.setTransition(mResultsScreen, transition);
diff --git a/tests/TransitionTests/src/com/android/transitiontests/Demo2.java b/tests/TransitionTests/src/com/android/transitiontests/Demo2.java
index 334b777..0f3257b 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/Demo2.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/Demo2.java
@@ -57,10 +57,10 @@
             }
 
             TransitionSet transition = new TransitionSet();
-            transition.addTransition(new Fade().addTargetId(R.id.resultsText).
-                    addTargetId(R.id.resultsList)).
-                    addTransition(new ChangeBounds().addTargetId(R.id.searchContainer)).
-                    addTransition(new Recolor().addTargetId(R.id.container));
+            transition.addTransition(new Fade().addTarget(R.id.resultsText).
+                    addTarget(R.id.resultsList)).
+                    addTransition(new ChangeBounds().addTarget(R.id.searchContainer)).
+                    addTransition(new Recolor().addTarget(R.id.container));
             mTransitionManager = new TransitionManager();
             mTransitionManager.setTransition(mSearchScreen, transition);
             mTransitionManager.setTransition(mResultsScreen, transition);
diff --git a/tests/TransitionTests/src/com/android/transitiontests/Demo4.java b/tests/TransitionTests/src/com/android/transitiontests/Demo4.java
index d1c3358..3aadbb0 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/Demo4.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/Demo4.java
@@ -46,17 +46,17 @@
 
         TransitionSet transitionToResults = new TransitionSet();
         Fade fade = new Fade();
-        fade.addTargetId(R.id.resultsText).addTargetId(R.id.resultsList);
+        fade.addTarget(R.id.resultsText).addTarget(R.id.resultsList);
         fade.setStartDelay(300);
         fade.setDuration(1000);
         transitionToResults.addTransition(fade).
-                addTransition(new ChangeBounds().addTargetId(R.id.searchContainer)).
-                addTransition(new Recolor().addTargetId(R.id.container));
+                addTransition(new ChangeBounds().addTarget(R.id.searchContainer)).
+                addTransition(new Recolor().addTarget(R.id.container));
 
         TransitionSet transitionToSearch = new TransitionSet();
         transitionToSearch.addTransition(fade).
-                addTransition(new ChangeBounds().addTargetId(R.id.searchContainer)).
-                addTransition(new Recolor().addTargetId(R.id.container));
+                addTransition(new ChangeBounds().addTarget(R.id.searchContainer)).
+                addTransition(new Recolor().addTarget(R.id.container));
 
         mTransitionManager = new TransitionManager();
         mTransitionManager.setTransition(mSearchScreen, transitionToSearch);
diff --git a/tests/TransitionTests/src/com/android/transitiontests/FadingTest.java b/tests/TransitionTests/src/com/android/transitiontests/FadingTest.java
index 000ea9b..29fb868 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/FadingTest.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/FadingTest.java
@@ -34,8 +34,8 @@
     Scene mCurrentScene;
 
     static {
-        sFade.addTargetId(R.id.removingButton).addTargetId(R.id.invisibleButton).
-                addTargetId(R.id.goneButton);
+        sFade.addTarget(R.id.removingButton).addTarget(R.id.invisibleButton).
+                addTarget(R.id.goneButton);
     }
 
     @Override
diff --git a/tests/TransitionTests/src/com/android/transitiontests/InterruptionTest.java b/tests/TransitionTests/src/com/android/transitiontests/InterruptionTest.java
index 70257bb..c26e93f 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/InterruptionTest.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/InterruptionTest.java
@@ -53,9 +53,9 @@
         mScene4RB = (RadioButton) findViewById(R.id.scene4RB);
 
         ChangeBounds changeBounds1 = new ChangeBounds();
-        changeBounds1.addTargetId(R.id.button);
+        changeBounds1.addTarget(R.id.button);
         ChangeBounds changeBounds2 = new ChangeBounds();
-        changeBounds2.addTargetId(R.id.button1);
+        changeBounds2.addTarget(R.id.button1);
 
         mSequencedMove.addTransition(changeBounds1).addTransition(changeBounds2);
         mSequencedMove.setDuration(1000);
diff --git a/tests/TransitionTests/src/com/android/transitiontests/LoginActivity.java b/tests/TransitionTests/src/com/android/transitiontests/LoginActivity.java
index 34ec6cc..92bbb85 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/LoginActivity.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/LoginActivity.java
@@ -54,9 +54,9 @@
 
         // Custom transitions in/out of NewUser screen - slide in the 2nd password UI
         TransitionSet slider = new TransitionSet();
-        slider.addTransition(new Slide().addTargetId(R.id.retype).addTargetId(R.id.retypeEdit));
-        slider.addTransition(new Recolor().addTargetId(R.id.password).
-                addTargetId(R.id.passwordEdit));
+        slider.addTransition(new Slide().addTarget(R.id.retype).addTarget(R.id.retypeEdit));
+        slider.addTransition(new Recolor().addTarget(R.id.password).
+                addTarget(R.id.passwordEdit));
         slider.addTransition(new Fade());
         mTransitionManager.setTransition(mLoginScene, mNewUserScene, slider);
         mTransitionManager.setTransition(mPasswordScene, mNewUserScene, slider);
@@ -64,8 +64,8 @@
         mTransitionManager.setTransition(mNewUserScene, mPasswordScene, slider);
 
         // Custom transitions with recoloring password field
-        Transition colorizer = new Recolor().addTargetId(R.id.password).
-                addTargetId(R.id.passwordEdit);
+        Transition colorizer = new Recolor().addTarget(R.id.password).
+                addTarget(R.id.passwordEdit);
         mTransitionManager.setTransition(mLoginScene, mPasswordScene, colorizer);
         mTransitionManager.setTransition(mPasswordScene, mLoginScene, colorizer);
 
diff --git a/tests/TransitionTests/src/com/android/transitiontests/ScenesTestv21.java b/tests/TransitionTests/src/com/android/transitiontests/ScenesTestv21.java
index c6011f2..ecf5ef3 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/ScenesTestv21.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/ScenesTestv21.java
@@ -47,17 +47,17 @@
 
         TransitionSet transitionToResults = new TransitionSet();
         Fade fade = new Fade();
-        fade.addTargetId(R.id.resultsText).addTargetId(R.id.resultsList);
+        fade.addTarget(R.id.resultsText).addTarget(R.id.resultsList);
         fade.setStartDelay(300);
         transitionToResults.addTransition(fade);
-        transitionToResults.addTransition(new ChangeBounds().addTargetId(R.id.searchContainer));
-        transitionToResults.addTransition(new Recolor().addTargetId(R.id.container));
+        transitionToResults.addTransition(new ChangeBounds().addTarget(R.id.searchContainer));
+        transitionToResults.addTransition(new Recolor().addTarget(R.id.container));
 
         TransitionSet transitionToSearch = new TransitionSet();
-        transitionToSearch.addTransition(new Fade().addTargetId(R.id.resultsText).
-                addTargetId(R.id.resultsList));
-        transitionToSearch.addTransition(new ChangeBounds().addTargetId(R.id.searchContainer));
-        transitionToSearch.addTransition(new Recolor().addTargetId(R.id.container));
+        transitionToSearch.addTransition(new Fade().addTarget(R.id.resultsText).
+                addTarget(R.id.resultsList));
+        transitionToSearch.addTransition(new ChangeBounds().addTarget(R.id.searchContainer));
+        transitionToSearch.addTransition(new Recolor().addTarget(R.id.container));
         mTransitionManager = new TransitionManager();
         mTransitionManager.setTransition(mSearchScreen, transitionToSearch);
         mTransitionManager.setTransition(mResultsScreen, transitionToResults);
diff --git a/tests/TransitionTests/src/com/android/transitiontests/SequenceTest.java b/tests/TransitionTests/src/com/android/transitiontests/SequenceTest.java
index ab1dc26..c550e92 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/SequenceTest.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/SequenceTest.java
@@ -51,9 +51,9 @@
         mScene1 = Scene.getSceneForLayout(mSceneRoot, R.layout.fading_test, this);
         mScene2 = Scene.getSceneForLayout(mSceneRoot, R.layout.fading_test_scene_2, this);
 
-        Transition fade1 = new Fade().addTargetId(R.id.removingButton);
-        Transition fade2 = new Fade().addTargetId(R.id.invisibleButton);
-        Transition fade3 = new Fade().addTargetId(R.id.goneButton);
+        Transition fade1 = new Fade().addTarget(R.id.removingButton);
+        Transition fade2 = new Fade().addTarget(R.id.invisibleButton);
+        Transition fade3 = new Fade().addTarget(R.id.goneButton);
         TransitionSet fader = new TransitionSet().
                 setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
         fader.addTransition(fade1).addTransition(fade2).addTransition(fade3).
diff --git a/tests/TransitionTests/src/com/android/transitiontests/SequenceTestSimple.java b/tests/TransitionTests/src/com/android/transitiontests/SequenceTestSimple.java
index 52c21c9..92b169e 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/SequenceTestSimple.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/SequenceTestSimple.java
@@ -52,14 +52,14 @@
 
         TransitionSet fader = new TransitionSet().
                 setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
-        fader.addTransition(new Fade().addTargetId(R.id.removingButton));
-        fader.addTransition(new ChangeBounds().addTargetId(R.id.sceneSwitchButton));
+        fader.addTransition(new Fade().addTarget(R.id.removingButton));
+        fader.addTransition(new ChangeBounds().addTarget(R.id.sceneSwitchButton));
         sequencedFade = fader;
 
         sequencedFadeReverse = new TransitionSet().
                 setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
-        sequencedFadeReverse.addTransition(new ChangeBounds().addTargetId(R.id.sceneSwitchButton));
-        sequencedFadeReverse.addTransition(new Fade().addTargetId(R.id.removingButton));
+        sequencedFadeReverse.addTransition(new ChangeBounds().addTarget(R.id.sceneSwitchButton));
+        sequencedFadeReverse.addTransition(new Fade().addTarget(R.id.removingButton));
 
         mCurrentScene = mScene1;
     }
diff --git a/tests/TransitionTests/src/com/android/transitiontests/SurfaceAndTextureViews.java b/tests/TransitionTests/src/com/android/transitiontests/SurfaceAndTextureViews.java
index 05af044..9b246ad 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/SurfaceAndTextureViews.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/SurfaceAndTextureViews.java
@@ -67,8 +67,8 @@
         container.addView(mTextureView);
 
         final TransitionSet transition = new TransitionSet();
-        transition.addTransition(new ChangeBounds()).addTransition(new Crossfade().addTargetId(0).
-                addTargetId(1).addTargetId(2));
+        transition.addTransition(new ChangeBounds()).addTransition(new Crossfade().addTarget(0).
+                addTarget(1).addTarget(2));
 
         toggleButton.setOnClickListener(new View.OnClickListener() {
             @Override