Loading api/current.txt +8 −2 Original line number Diff line number Diff line Loading @@ -25516,12 +25516,18 @@ package android.transition { 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(); Loading @@ -25531,8 +25537,8 @@ package android.transition { 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); core/java/android/transition/Transition.java +317 −14 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import android.view.View; import android.view.ViewGroup; import android.view.ViewOverlay; import android.widget.ListView; import android.widget.Spinner; import java.util.ArrayList; import java.util.List; Loading Loading @@ -100,6 +101,12 @@ public abstract class Transition implements Cloneable { 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; Loading Loading @@ -430,10 +437,8 @@ public abstract class Transition implements Cloneable { 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); Loading Loading @@ -504,6 +509,21 @@ public abstract class Transition implements Cloneable { * 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; } Loading Loading @@ -652,9 +672,9 @@ public abstract class Transition implements Cloneable { * @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); } Loading @@ -671,13 +691,219 @@ public abstract class Transition implements Cloneable { * 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); } return this; } /** * 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 Loading @@ -686,18 +912,18 @@ public abstract class Transition implements Cloneable { * 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 Loading Loading @@ -842,15 +1068,30 @@ public abstract class Transition implements Cloneable { // 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); Loading @@ -861,7 +1102,7 @@ public abstract class Transition implements Cloneable { mStartValues.idValues.put((int) id, values); } } else { mStartValues.itemIdValues.put(id, values); mStartValues.itemIdValues.put(itemId, values); } } else { if (!isListViewItem) { Loading @@ -870,10 +1111,25 @@ public abstract class Transition implements Cloneable { 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); Loading Loading @@ -1356,4 +1612,51 @@ public abstract class Transition implements Cloneable { 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; } } } core/java/android/transition/TransitionInflater.java +1 −1 Original line number Diff line number Diff line Loading @@ -235,7 +235,7 @@ public class TransitionInflater { int numTargets = targetIds.size(); if (numTargets > 0) { for (int i = 0; i < numTargets; ++i) { transition.addTargetId(targetIds.get(i)); transition.addTarget(targetIds.get(i)); } } } Loading core/java/android/transition/TransitionSet.java +14 −10 Original line number Diff line number Diff line Loading @@ -155,8 +155,8 @@ public class TransitionSet extends Transition { } @Override public TransitionSet addTargetId(int targetId) { return (TransitionSet) super.addTargetId(targetId); public TransitionSet addTarget(int targetId) { return (TransitionSet) super.addTarget(targetId); } @Override Loading @@ -165,8 +165,8 @@ public class TransitionSet extends Transition { } @Override public TransitionSet removeTargetId(int targetId) { return (TransitionSet) super.removeTargetId(targetId); public TransitionSet removeTarget(int targetId) { return (TransitionSet) super.removeTarget(targetId); } @Override Loading Loading @@ -278,22 +278,26 @@ public class TransitionSet extends Transition { @Override public void captureStartValues(TransitionValues transitionValues) { int targetId = transitionValues.view.getId(); if (isValidTarget(transitionValues.view, targetId)) { for (Transition childTransition : mTransitions) { if (childTransition.isValidTarget(transitionValues.view, targetId)) { childTransition.captureStartValues(transitionValues); } } } } @Override public void captureEndValues(TransitionValues transitionValues) { int targetId = transitionValues.view.getId(); if (isValidTarget(transitionValues.view, targetId)) { for (Transition childTransition : mTransitions) { if (childTransition.isValidTarget(transitionValues.view, targetId)) { childTransition.captureEndValues(transitionValues); } } } } /** @hide */ @Override Loading core/res/res/values/attrs.xml +1 −1 Original line number Diff line number Diff line Loading @@ -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. Loading Loading
api/current.txt +8 −2 Original line number Diff line number Diff line Loading @@ -25516,12 +25516,18 @@ package android.transition { 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(); Loading @@ -25531,8 +25537,8 @@ package android.transition { 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);
core/java/android/transition/Transition.java +317 −14 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import android.view.View; import android.view.ViewGroup; import android.view.ViewOverlay; import android.widget.ListView; import android.widget.Spinner; import java.util.ArrayList; import java.util.List; Loading Loading @@ -100,6 +101,12 @@ public abstract class Transition implements Cloneable { 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; Loading Loading @@ -430,10 +437,8 @@ public abstract class Transition implements Cloneable { 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); Loading Loading @@ -504,6 +509,21 @@ public abstract class Transition implements Cloneable { * 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; } Loading Loading @@ -652,9 +672,9 @@ public abstract class Transition implements Cloneable { * @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); } Loading @@ -671,13 +691,219 @@ public abstract class Transition implements Cloneable { * 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); } return this; } /** * 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 Loading @@ -686,18 +912,18 @@ public abstract class Transition implements Cloneable { * 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 Loading Loading @@ -842,15 +1068,30 @@ public abstract class Transition implements Cloneable { // 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); Loading @@ -861,7 +1102,7 @@ public abstract class Transition implements Cloneable { mStartValues.idValues.put((int) id, values); } } else { mStartValues.itemIdValues.put(id, values); mStartValues.itemIdValues.put(itemId, values); } } else { if (!isListViewItem) { Loading @@ -870,10 +1111,25 @@ public abstract class Transition implements Cloneable { 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); Loading Loading @@ -1356,4 +1612,51 @@ public abstract class Transition implements Cloneable { 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; } } }
core/java/android/transition/TransitionInflater.java +1 −1 Original line number Diff line number Diff line Loading @@ -235,7 +235,7 @@ public class TransitionInflater { int numTargets = targetIds.size(); if (numTargets > 0) { for (int i = 0; i < numTargets; ++i) { transition.addTargetId(targetIds.get(i)); transition.addTarget(targetIds.get(i)); } } } Loading
core/java/android/transition/TransitionSet.java +14 −10 Original line number Diff line number Diff line Loading @@ -155,8 +155,8 @@ public class TransitionSet extends Transition { } @Override public TransitionSet addTargetId(int targetId) { return (TransitionSet) super.addTargetId(targetId); public TransitionSet addTarget(int targetId) { return (TransitionSet) super.addTarget(targetId); } @Override Loading @@ -165,8 +165,8 @@ public class TransitionSet extends Transition { } @Override public TransitionSet removeTargetId(int targetId) { return (TransitionSet) super.removeTargetId(targetId); public TransitionSet removeTarget(int targetId) { return (TransitionSet) super.removeTarget(targetId); } @Override Loading Loading @@ -278,22 +278,26 @@ public class TransitionSet extends Transition { @Override public void captureStartValues(TransitionValues transitionValues) { int targetId = transitionValues.view.getId(); if (isValidTarget(transitionValues.view, targetId)) { for (Transition childTransition : mTransitions) { if (childTransition.isValidTarget(transitionValues.view, targetId)) { childTransition.captureStartValues(transitionValues); } } } } @Override public void captureEndValues(TransitionValues transitionValues) { int targetId = transitionValues.view.getId(); if (isValidTarget(transitionValues.view, targetId)) { for (Transition childTransition : mTransitions) { if (childTransition.isValidTarget(transitionValues.view, targetId)) { childTransition.captureEndValues(transitionValues); } } } } /** @hide */ @Override Loading
core/res/res/values/attrs.xml +1 −1 Original line number Diff line number Diff line Loading @@ -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. Loading