summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/current.xml342
-rw-r--r--core/java/android/animation/AnimatorInflater.java38
-rw-r--r--core/java/android/animation/AnimatorSet.java56
-rw-r--r--core/java/android/animation/FloatKeyframeSet.java134
-rw-r--r--core/java/android/animation/IntKeyframeSet.java133
-rw-r--r--core/java/android/animation/Keyframe.java244
-rw-r--r--core/java/android/animation/KeyframeSet.java127
-rw-r--r--core/java/android/animation/ObjectAnimator.java64
-rw-r--r--core/java/android/animation/PropertyValuesHolder.java252
-rwxr-xr-xcore/java/android/animation/ValueAnimator.java110
-rw-r--r--core/java/android/view/View.java2
11 files changed, 857 insertions, 645 deletions
diff --git a/api/current.xml b/api/current.xml
index 07f298e..d682155 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -17874,7 +17874,7 @@
</class>
<class name="Keyframe"
extends="java.lang.Object"
- abstract="false"
+ abstract="true"
static="false"
final="false"
deprecated="not deprecated"
@@ -17889,137 +17889,156 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="fraction" type="float">
-</parameter>
-<parameter name="value" type="java.lang.Object">
-</parameter>
</constructor>
-<constructor name="Keyframe"
- type="android.animation.Keyframe"
+<method name="clone"
+ return="android.animation.Keyframe"
+ abstract="true"
+ native="false"
+ synchronized="false"
static="false"
final="false"
deprecated="not deprecated"
visibility="public"
>
-<parameter name="fraction" type="float">
-</parameter>
-<parameter name="value" type="java.lang.Float">
-</parameter>
-</constructor>
-<constructor name="Keyframe"
- type="android.animation.Keyframe"
+</method>
+<method name="getFraction"
+ return="float"
+ abstract="false"
+ native="false"
+ synchronized="false"
static="false"
final="false"
deprecated="not deprecated"
visibility="public"
>
-<parameter name="fraction" type="float">
-</parameter>
-<parameter name="value" type="java.lang.Integer">
-</parameter>
-</constructor>
-<constructor name="Keyframe"
- type="android.animation.Keyframe"
+</method>
+<method name="getInterpolator"
+ return="android.animation.TimeInterpolator"
+ abstract="false"
+ native="false"
+ synchronized="false"
static="false"
final="false"
deprecated="not deprecated"
visibility="public"
>
-<parameter name="fraction" type="float">
-</parameter>
-<parameter name="value" type="java.lang.Double">
-</parameter>
-</constructor>
-<constructor name="Keyframe"
- type="android.animation.Keyframe"
+</method>
+<method name="getType"
+ return="java.lang.Class"
+ abstract="false"
+ native="false"
+ synchronized="false"
static="false"
final="false"
deprecated="not deprecated"
visibility="public"
>
-<parameter name="fraction" type="float">
-</parameter>
-<parameter name="value" type="int">
-</parameter>
-</constructor>
-<constructor name="Keyframe"
- type="android.animation.Keyframe"
+</method>
+<method name="getValue"
+ return="java.lang.Object"
+ abstract="true"
+ native="false"
+ synchronized="false"
static="false"
final="false"
deprecated="not deprecated"
visibility="public"
>
-<parameter name="fraction" type="float">
-</parameter>
-<parameter name="value" type="float">
-</parameter>
-</constructor>
-<constructor name="Keyframe"
- type="android.animation.Keyframe"
+</method>
+<method name="hasValue"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
static="false"
final="false"
deprecated="not deprecated"
visibility="public"
>
+</method>
+<method name="ofFloat"
+ return="android.animation.Keyframe"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
<parameter name="fraction" type="float">
</parameter>
-<parameter name="value" type="double">
+<parameter name="value" type="float">
</parameter>
-</constructor>
-<method name="clone"
+</method>
+<method name="ofFloat"
return="android.animation.Keyframe"
abstract="false"
native="false"
synchronized="false"
- static="false"
+ static="true"
final="false"
deprecated="not deprecated"
visibility="public"
>
+<parameter name="fraction" type="float">
+</parameter>
</method>
-<method name="getFraction"
- return="float"
+<method name="ofInt"
+ return="android.animation.Keyframe"
abstract="false"
native="false"
synchronized="false"
- static="false"
+ static="true"
final="false"
deprecated="not deprecated"
visibility="public"
>
+<parameter name="fraction" type="float">
+</parameter>
+<parameter name="value" type="int">
+</parameter>
</method>
-<method name="getInterpolator"
- return="android.animation.TimeInterpolator"
+<method name="ofInt"
+ return="android.animation.Keyframe"
abstract="false"
native="false"
synchronized="false"
- static="false"
+ static="true"
final="false"
deprecated="not deprecated"
visibility="public"
>
+<parameter name="fraction" type="float">
+</parameter>
</method>
-<method name="getType"
- return="java.lang.Class"
+<method name="ofObject"
+ return="android.animation.Keyframe"
abstract="false"
native="false"
synchronized="false"
- static="false"
+ static="true"
final="false"
deprecated="not deprecated"
visibility="public"
>
+<parameter name="fraction" type="float">
+</parameter>
+<parameter name="value" type="java.lang.Object">
+</parameter>
</method>
-<method name="getValue"
- return="java.lang.Object"
+<method name="ofObject"
+ return="android.animation.Keyframe"
abstract="false"
native="false"
synchronized="false"
- static="false"
+ static="true"
final="false"
deprecated="not deprecated"
visibility="public"
>
+<parameter name="fraction" type="float">
+</parameter>
</method>
<method name="setFraction"
return="void"
@@ -18049,7 +18068,7 @@
</method>
<method name="setValue"
return="void"
- abstract="false"
+ abstract="true"
native="false"
synchronized="false"
static="false"
@@ -18456,23 +18475,6 @@
visibility="public"
>
</method>
-<method name="ofDouble"
- return="android.animation.ObjectAnimator"
- abstract="false"
- native="false"
- synchronized="false"
- static="true"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="target" type="java.lang.Object">
-</parameter>
-<parameter name="propertyName" type="java.lang.String">
-</parameter>
-<parameter name="values" type="double...">
-</parameter>
-</method>
<method name="ofFloat"
return="android.animation.ObjectAnimator"
abstract="false"
@@ -18507,23 +18509,6 @@
<parameter name="values" type="int...">
</parameter>
</method>
-<method name="ofLong"
- return="android.animation.ObjectAnimator"
- abstract="false"
- native="false"
- synchronized="false"
- static="true"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="target" type="java.lang.Object">
-</parameter>
-<parameter name="propertyName" type="java.lang.String">
-</parameter>
-<parameter name="values" type="long...">
-</parameter>
-</method>
<method name="ofObject"
return="android.animation.ObjectAnimator"
abstract="false"
@@ -18626,21 +18611,6 @@
visibility="public"
>
</method>
-<method name="ofDouble"
- return="android.animation.PropertyValuesHolder"
- abstract="false"
- native="false"
- synchronized="false"
- static="true"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="propertyName" type="java.lang.String">
-</parameter>
-<parameter name="values" type="double...">
-</parameter>
-</method>
<method name="ofFloat"
return="android.animation.PropertyValuesHolder"
abstract="false"
@@ -18686,21 +18656,6 @@
<parameter name="values" type="android.animation.Keyframe...">
</parameter>
</method>
-<method name="ofLong"
- return="android.animation.PropertyValuesHolder"
- abstract="false"
- native="false"
- synchronized="false"
- static="true"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="propertyName" type="java.lang.String">
-</parameter>
-<parameter name="values" type="long...">
-</parameter>
-</method>
<method name="ofObject"
return="android.animation.PropertyValuesHolder"
abstract="false"
@@ -18718,19 +18673,6 @@
<parameter name="values" type="java.lang.Object...">
</parameter>
</method>
-<method name="setDoubleValues"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="values" type="double...">
-</parameter>
-</method>
<method name="setEvaluator"
return="void"
abstract="false"
@@ -18796,19 +18738,6 @@
<parameter name="values" type="android.animation.Keyframe...">
</parameter>
</method>
-<method name="setLongValues"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="values" type="long...">
-</parameter>
-</method>
<method name="setObjectValues"
return="void"
abstract="false"
@@ -19083,19 +19012,6 @@
visibility="public"
>
</method>
-<method name="ofDouble"
- return="android.animation.ValueAnimator"
- abstract="false"
- native="false"
- synchronized="false"
- static="true"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="values" type="double...">
-</parameter>
-</method>
<method name="ofFloat"
return="android.animation.ValueAnimator"
abstract="false"
@@ -19122,19 +19038,6 @@
<parameter name="values" type="int...">
</parameter>
</method>
-<method name="ofLong"
- return="android.animation.ValueAnimator"
- abstract="false"
- native="false"
- synchronized="false"
- static="true"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="values" type="long...">
-</parameter>
-</method>
<method name="ofObject"
return="android.animation.ValueAnimator"
abstract="false"
@@ -19211,19 +19114,6 @@
<parameter name="playTime" type="long">
</parameter>
</method>
-<method name="setDoubleValues"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="values" type="double...">
-</parameter>
-</method>
<method name="setDuration"
return="android.animation.ValueAnimator"
abstract="false"
@@ -19302,19 +19192,6 @@
<parameter name="value" type="android.animation.TimeInterpolator">
</parameter>
</method>
-<method name="setLongValues"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="values" type="long...">
-</parameter>
-</method>
<method name="setObjectValues"
return="void"
abstract="false"
@@ -166627,6 +166504,17 @@
visibility="public"
>
</field>
+<field name="NETWORK_TYPE_EHRPD"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="14"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="NETWORK_TYPE_EVDO_0"
type="int"
transient="false"
@@ -166715,6 +166603,17 @@
visibility="public"
>
</field>
+<field name="NETWORK_TYPE_LTE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="13"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="NETWORK_TYPE_UMTS"
type="int"
transient="false"
@@ -166770,6 +166669,17 @@
visibility="public"
>
</field>
+<field name="PHONE_TYPE_SIP"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="3"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="SIM_STATE_ABSENT"
type="int"
transient="false"
@@ -250796,7 +250706,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="buffer" type="byte[]">
+<parameter name="dst" type="byte[]">
</parameter>
<exception name="IOException" type="java.io.IOException">
</exception>
@@ -250811,11 +250721,11 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="buffer" type="byte[]">
+<parameter name="dst" type="byte[]">
</parameter>
<parameter name="offset" type="int">
</parameter>
-<parameter name="count" type="int">
+<parameter name="byteCount" type="int">
</parameter>
<exception name="IOException" type="java.io.IOException">
</exception>
@@ -251056,7 +250966,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="buffer" type="byte[]">
+<parameter name="dst" type="byte[]">
</parameter>
<exception name="IOException" type="java.io.IOException">
</exception>
@@ -251071,11 +250981,11 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="buffer" type="byte[]">
+<parameter name="dst" type="byte[]">
</parameter>
<parameter name="offset" type="int">
</parameter>
-<parameter name="length" type="int">
+<parameter name="byteCount" type="int">
</parameter>
<exception name="IOException" type="java.io.IOException">
</exception>
@@ -253982,7 +253892,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="buffer" type="byte[]">
+<parameter name="dst" type="byte[]">
</parameter>
<exception name="IOException" type="java.io.IOException">
</exception>
@@ -253997,11 +253907,11 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="buffer" type="byte[]">
+<parameter name="dst" type="byte[]">
</parameter>
<parameter name="offset" type="int">
</parameter>
-<parameter name="length" type="int">
+<parameter name="byteCount" type="int">
</parameter>
<exception name="IOException" type="java.io.IOException">
</exception>
@@ -257802,7 +257712,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="buffer" type="byte[]">
+<parameter name="dst" type="byte[]">
</parameter>
<exception name="IOException" type="java.io.IOException">
</exception>
@@ -257817,11 +257727,11 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="buffer" type="byte[]">
+<parameter name="dst" type="byte[]">
</parameter>
<parameter name="offset" type="int">
</parameter>
-<parameter name="count" type="int">
+<parameter name="byteCount" type="int">
</parameter>
<exception name="IOException" type="java.io.IOException">
</exception>
@@ -283974,9 +283884,9 @@
>
<parameter name="uri" type="java.net.URI">
</parameter>
-<parameter name="sa" type="java.net.SocketAddress">
+<parameter name="address" type="java.net.SocketAddress">
</parameter>
-<parameter name="ioe" type="java.io.IOException">
+<parameter name="failure" type="java.io.IOException">
</parameter>
</method>
<method name="getDefault"
@@ -284075,7 +283985,7 @@
>
<parameter name="uri" type="java.net.URI">
</parameter>
-<parameter name="conn" type="java.net.URLConnection">
+<parameter name="connection" type="java.net.URLConnection">
</parameter>
<exception name="IOException" type="java.io.IOException">
</exception>
diff --git a/core/java/android/animation/AnimatorInflater.java b/core/java/android/animation/AnimatorInflater.java
index 4a6c460..b96391a 100644
--- a/core/java/android/animation/AnimatorInflater.java
+++ b/core/java/android/animation/AnimatorInflater.java
@@ -51,8 +51,6 @@ public class AnimatorInflater {
*/
private static final int VALUE_TYPE_FLOAT = 0;
private static final int VALUE_TYPE_INT = 1;
- private static final int VALUE_TYPE_DOUBLE = 2;
- private static final int VALUE_TYPE_LONG = 3;
private static final int VALUE_TYPE_COLOR = 4;
private static final int VALUE_TYPE_CUSTOM = 5;
@@ -242,42 +240,6 @@ public class AnimatorInflater {
}
break;
- case VALUE_TYPE_LONG: {
- int valueFrom;
- int valueTo;
- if (hasFrom) {
- valueFrom = a.getInteger(com.android.internal.R.styleable.Animator_valueFrom, 0);
- if (hasTo) {
- valueTo = a.getInteger(com.android.internal.R.styleable.Animator_valueTo, 0);
- anim.setLongValues(valueFrom, valueTo);
- } else {
- anim.setLongValues(valueFrom);
- }
- } else {
- valueTo = a.getInteger(com.android.internal.R.styleable.Animator_valueTo, 0);
- anim.setLongValues(valueTo);
- }
- }
- break;
-
- case VALUE_TYPE_DOUBLE: {
- double valueFrom;
- double valueTo;
- if (hasFrom) {
- valueFrom = a.getFloat(com.android.internal.R.styleable.Animator_valueFrom, 0f);
- if (hasTo) {
- valueTo = a.getFloat(com.android.internal.R.styleable.Animator_valueTo, 0f);
- anim.setDoubleValues(valueFrom, valueTo);
- } else {
- anim.setDoubleValues(valueFrom);
- }
- } else {
- valueTo = a.getFloat(com.android.internal.R.styleable.Animator_valueTo, 0f);
- anim.setDoubleValues(valueTo);
- }
- }
- break;
-
case VALUE_TYPE_CUSTOM: {
// TODO: How to get an 'Object' value?
float valueFrom;
diff --git a/core/java/android/animation/AnimatorSet.java b/core/java/android/animation/AnimatorSet.java
index 8fc45f4..9ba9388 100644
--- a/core/java/android/animation/AnimatorSet.java
+++ b/core/java/android/animation/AnimatorSet.java
@@ -362,14 +362,18 @@ public final class AnimatorSet extends Animator {
// dependencies on all of the nodes. For example, we don't want to start an animation
// when some other animation also wants to start when the first animation begins.
final ArrayList<Node> nodesToStart = new ArrayList<Node>();
- for (Node node : mSortedNodes) {
+ int numSortedNodes = mSortedNodes.size();
+ for (int i = 0; i < numSortedNodes; ++i) {
+ Node node = mSortedNodes.get(i);
if (mSetListener == null) {
mSetListener = new AnimatorSetListener(this);
}
if (node.dependencies == null || node.dependencies.size() == 0) {
nodesToStart.add(node);
} else {
- for (Dependency dependency : node.dependencies) {
+ int numDependencies = node.dependencies.size();
+ for (int j = 0; j < numDependencies; ++j) {
+ Dependency dependency = node.dependencies.get(j);
dependency.node.animation.addListener(
new DependencyListener(this, node, dependency.rule));
}
@@ -389,7 +393,9 @@ public final class AnimatorSet extends Animator {
delayAnim.setDuration(mStartDelay);
delayAnim.addListener(new AnimatorListenerAdapter() {
public void onAnimationEnd(Animator anim) {
- for (Node node : nodesToStart) {
+ int numNodes = nodesToStart.size();
+ for (int i = 0; i < numNodes; ++i) {
+ Node node = nodesToStart.get(i);
node.animation.start();
mPlayingSet.add(node.animation);
}
@@ -399,8 +405,9 @@ public final class AnimatorSet extends Animator {
if (mListeners != null) {
ArrayList<AnimatorListener> tmpListeners =
(ArrayList<AnimatorListener>) mListeners.clone();
- for (AnimatorListener listener : tmpListeners) {
- listener.onAnimationStart(this);
+ int numListeners = tmpListeners.size();
+ for (int i = 0; i < numListeners; ++i) {
+ tmpListeners.get(i).onAnimationStart(this);
}
}
}
@@ -540,7 +547,9 @@ public final class AnimatorSet extends Animator {
return;
}
Dependency dependencyToRemove = null;
- for (Dependency dependency : mNode.tmpDependencies) {
+ int numDependencies = mNode.tmpDependencies.size();
+ for (int i = 0; i < numDependencies; ++i) {
+ Dependency dependency = mNode.tmpDependencies.get(i);
if (dependency.rule == mRule &&
dependency.node.animation == dependencyAnimation) {
// rule fired - remove the dependency and listener and check to
@@ -571,8 +580,9 @@ public final class AnimatorSet extends Animator {
public void onAnimationCancel(Animator animation) {
if (mPlayingSet.size() == 0) {
if (mListeners != null) {
- for (AnimatorListener listener : mListeners) {
- listener.onAnimationCancel(mAnimatorSet);
+ int numListeners = mListeners.size();
+ for (int i = 0; i < numListeners; ++i) {
+ mListeners.get(i).onAnimationCancel(mAnimatorSet);
}
}
}
@@ -586,8 +596,9 @@ public final class AnimatorSet extends Animator {
animNode.done = true;
ArrayList<Node> sortedNodes = mAnimatorSet.mSortedNodes;
boolean allDone = true;
- for (Node node : sortedNodes) {
- if (!node.done) {
+ int numSortedNodes = sortedNodes.size();
+ for (int i = 0; i < numSortedNodes; ++i) {
+ if (!sortedNodes.get(i).done) {
allDone = false;
break;
}
@@ -598,8 +609,9 @@ public final class AnimatorSet extends Animator {
if (mListeners != null) {
ArrayList<AnimatorListener> tmpListeners =
(ArrayList<AnimatorListener>) mListeners.clone();
- for (AnimatorListener listener : tmpListeners) {
- listener.onAnimationEnd(mAnimatorSet);
+ int numListeners = tmpListeners.size();
+ for (int i = 0; i < numListeners; ++i) {
+ tmpListeners.get(i).onAnimationEnd(mAnimatorSet);
}
}
}
@@ -629,17 +641,23 @@ public final class AnimatorSet extends Animator {
if (mNeedsSort) {
mSortedNodes.clear();
ArrayList<Node> roots = new ArrayList<Node>();
- for (Node node : mNodes) {
+ int numNodes = mNodes.size();
+ for (int i = 0; i < numNodes; ++i) {
+ Node node = mNodes.get(i);
if (node.dependencies == null || node.dependencies.size() == 0) {
roots.add(node);
}
}
ArrayList<Node> tmpRoots = new ArrayList<Node>();
while (roots.size() > 0) {
- for (Node root : roots) {
+ int numRoots = roots.size();
+ for (int i = 0; i < numRoots; ++i) {
+ Node root = roots.get(i);
mSortedNodes.add(root);
if (root.nodeDependents != null) {
- for (Node node : root.nodeDependents) {
+ int numDependents = root.nodeDependents.size();
+ for (int j = 0; j < numDependents; ++j) {
+ Node node = root.nodeDependents.get(j);
node.nodeDependencies.remove(root);
if (node.nodeDependencies.size() == 0) {
tmpRoots.add(node);
@@ -660,9 +678,13 @@ public final class AnimatorSet extends Animator {
// Doesn't need sorting, but still need to add in the nodeDependencies list
// because these get removed as the event listeners fire and the dependencies
// are satisfied
- for (Node node : mNodes) {
+ int numNodes = mNodes.size();
+ for (int i = 0; i < numNodes; ++i) {
+ Node node = mNodes.get(i);
if (node.dependencies != null && node.dependencies.size() > 0) {
- for (Dependency dependency : node.dependencies) {
+ int numDependencies = node.dependencies.size();
+ for (int j = 0; j < numDependencies; ++j) {
+ Dependency dependency = node.dependencies.get(j);
if (node.nodeDependencies == null) {
node.nodeDependencies = new ArrayList<Node>();
}
diff --git a/core/java/android/animation/FloatKeyframeSet.java b/core/java/android/animation/FloatKeyframeSet.java
new file mode 100644
index 0000000..6fad4a68
--- /dev/null
+++ b/core/java/android/animation/FloatKeyframeSet.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.animation;
+
+import android.animation.Keyframe.FloatKeyframe;
+
+import java.util.ArrayList;
+
+/**
+ * This class holds a collection of FloatKeyframe objects and is called by ValueAnimator to calculate
+ * values between those keyframes for a given animation. The class internal to the animation
+ * package because it is an implementation detail of how Keyframes are stored and used.
+ *
+ * <p>This type-specific subclass of KeyframeSet, along with the other type-specific subclasses for
+ * int, long, and double, exists to speed up the getValue() method when there is no custom
+ * TypeEvaluator set for the animation, so that values can be calculated without autoboxing to the
+ * Object equivalents of these primitive types.</p>
+ */
+class FloatKeyframeSet extends KeyframeSet {
+ private float firstValue;
+ private float lastValue;
+ private float deltaValue;
+ private boolean firstTime = true;
+
+ public FloatKeyframeSet(FloatKeyframe... keyframes) {
+ super(keyframes);
+ }
+
+ @Override
+ public Object getValue(float fraction) {
+ return getFloatValue(fraction);
+ }
+
+ @Override
+ public FloatKeyframeSet clone() {
+ ArrayList<Keyframe> keyframes = mKeyframes;
+ int numKeyframes = mKeyframes.size();
+ FloatKeyframe[] newKeyframes = new FloatKeyframe[numKeyframes];
+ for (int i = 0; i < numKeyframes; ++i) {
+ newKeyframes[i] = (FloatKeyframe) keyframes.get(i).clone();
+ }
+ FloatKeyframeSet newSet = new FloatKeyframeSet(newKeyframes);
+ return newSet;
+ }
+
+ public float getFloatValue(float fraction) {
+ if (mNumKeyframes == 2) {
+ if (firstTime) {
+ firstTime = false;
+ firstValue = ((FloatKeyframe) mKeyframes.get(0)).getFloatValue();
+ lastValue = ((FloatKeyframe) mKeyframes.get(1)).getFloatValue();
+ deltaValue = lastValue - firstValue;
+ }
+ if (mInterpolator != null) {
+ fraction = mInterpolator.getInterpolation(fraction);
+ }
+ if (mEvaluator == null) {
+ return firstValue + fraction * deltaValue;
+ } else {
+ return ((Number)mEvaluator.evaluate(fraction, firstValue, lastValue)).floatValue();
+ }
+ }
+ if (fraction <= 0f) {
+ final FloatKeyframe prevKeyframe = (FloatKeyframe) mKeyframes.get(0);
+ final FloatKeyframe nextKeyframe = (FloatKeyframe) mKeyframes.get(1);
+ float prevValue = prevKeyframe.getFloatValue();
+ float nextValue = nextKeyframe.getFloatValue();
+ float prevFraction = prevKeyframe.getFraction();
+ float nextFraction = nextKeyframe.getFraction();
+ final TimeInterpolator interpolator = nextKeyframe.getInterpolator();
+ if (interpolator != null) {
+ fraction = interpolator.getInterpolation(fraction);
+ }
+ float intervalFraction = (fraction - prevFraction) / (nextFraction - prevFraction);
+ return mEvaluator == null ?
+ prevValue + fraction * (nextValue - prevValue) :
+ ((Number)mEvaluator.evaluate(intervalFraction, prevValue, nextValue)).
+ floatValue();
+ } else if (fraction >= 1f) {
+ final FloatKeyframe prevKeyframe = (FloatKeyframe) mKeyframes.get(mNumKeyframes - 2);
+ final FloatKeyframe nextKeyframe = (FloatKeyframe) mKeyframes.get(mNumKeyframes - 1);
+ float prevValue = prevKeyframe.getFloatValue();
+ float nextValue = nextKeyframe.getFloatValue();
+ float prevFraction = prevKeyframe.getFraction();
+ float nextFraction = nextKeyframe.getFraction();
+ final TimeInterpolator interpolator = nextKeyframe.getInterpolator();
+ if (interpolator != null) {
+ fraction = interpolator.getInterpolation(fraction);
+ }
+ float intervalFraction = (fraction - prevFraction) / (nextFraction - prevFraction);
+ return mEvaluator == null ?
+ prevValue + fraction * (nextValue - prevValue) :
+ ((Number)mEvaluator.evaluate(intervalFraction, prevValue, nextValue)).
+ floatValue();
+ }
+ FloatKeyframe prevKeyframe = (FloatKeyframe) mKeyframes.get(0);
+ for (int i = 1; i < mNumKeyframes; ++i) {
+ FloatKeyframe nextKeyframe = (FloatKeyframe) mKeyframes.get(i);
+ if (fraction < nextKeyframe.getFraction()) {
+ final TimeInterpolator interpolator = nextKeyframe.getInterpolator();
+ if (interpolator != null) {
+ fraction = interpolator.getInterpolation(fraction);
+ }
+ float intervalFraction = (fraction - prevKeyframe.getFraction()) /
+ (nextKeyframe.getFraction() - prevKeyframe.getFraction());
+ float prevValue = prevKeyframe.getFloatValue();
+ float nextValue = nextKeyframe.getFloatValue();
+ return mEvaluator == null ?
+ prevValue + fraction * (nextValue - prevValue) :
+ ((Number)mEvaluator.evaluate(intervalFraction, prevValue, nextValue)).
+ floatValue();
+ }
+ prevKeyframe = nextKeyframe;
+ }
+ // shouldn't get here
+ return ((Number)mKeyframes.get(mNumKeyframes - 1).getValue()).floatValue();
+ }
+
+}
+
diff --git a/core/java/android/animation/IntKeyframeSet.java b/core/java/android/animation/IntKeyframeSet.java
new file mode 100644
index 0000000..14a4e3a
--- /dev/null
+++ b/core/java/android/animation/IntKeyframeSet.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.animation;
+
+import android.animation.Keyframe.IntKeyframe;
+
+import java.util.ArrayList;
+
+/**
+ * This class holds a collection of IntKeyframe objects and is called by ValueAnimator to calculate
+ * values between those keyframes for a given animation. The class internal to the animation
+ * package because it is an implementation detail of how Keyframes are stored and used.
+ *
+ * <p>This type-specific subclass of KeyframeSet, along with the other type-specific subclasses for
+ * float, long, and double, exists to speed up the getValue() method when there is no custom
+ * TypeEvaluator set for the animation, so that values can be calculated without autoboxing to the
+ * Object equivalents of these primitive types.</p>
+ */
+class IntKeyframeSet extends KeyframeSet {
+ private int firstValue;
+ private int lastValue;
+ private int deltaValue;
+ private boolean firstTime = true;
+
+ public IntKeyframeSet(IntKeyframe... keyframes) {
+ super(keyframes);
+ }
+
+ @Override
+ public Object getValue(float fraction) {
+ return getIntValue(fraction);
+ }
+
+ @Override
+ public IntKeyframeSet clone() {
+ ArrayList<Keyframe> keyframes = mKeyframes;
+ int numKeyframes = mKeyframes.size();
+ IntKeyframe[] newKeyframes = new IntKeyframe[numKeyframes];
+ for (int i = 0; i < numKeyframes; ++i) {
+ newKeyframes[i] = (IntKeyframe) keyframes.get(i).clone();
+ }
+ IntKeyframeSet newSet = new IntKeyframeSet(newKeyframes);
+ return newSet;
+ }
+
+ public int getIntValue(float fraction) {
+ if (mNumKeyframes == 2) {
+ if (firstTime) {
+ firstTime = false;
+ firstValue = ((IntKeyframe) mKeyframes.get(0)).getIntValue();
+ lastValue = ((IntKeyframe) mKeyframes.get(1)).getIntValue();
+ deltaValue = lastValue - firstValue;
+ }
+ if (mInterpolator != null) {
+ fraction = mInterpolator.getInterpolation(fraction);
+ }
+ if (mEvaluator == null) {
+ return firstValue + (int)(fraction * deltaValue);
+ } else {
+ return ((Number)mEvaluator.evaluate(fraction, firstValue, lastValue)).intValue();
+ }
+ }
+ if (fraction <= 0f) {
+ final IntKeyframe prevKeyframe = (IntKeyframe) mKeyframes.get(0);
+ final IntKeyframe nextKeyframe = (IntKeyframe) mKeyframes.get(1);
+ int prevValue = prevKeyframe.getIntValue();
+ int nextValue = nextKeyframe.getIntValue();
+ float prevFraction = prevKeyframe.getFraction();
+ float nextFraction = nextKeyframe.getFraction();
+ final TimeInterpolator interpolator = nextKeyframe.getInterpolator();
+ if (interpolator != null) {
+ fraction = interpolator.getInterpolation(fraction);
+ }
+ float intervalFraction = (fraction - prevFraction) / (nextFraction - prevFraction);
+ return mEvaluator == null ?
+ prevValue + (int)(fraction * (nextValue - prevValue)) :
+ ((Number)mEvaluator.evaluate(intervalFraction, prevValue, nextValue)).
+ intValue();
+ } else if (fraction >= 1f) {
+ final IntKeyframe prevKeyframe = (IntKeyframe) mKeyframes.get(mNumKeyframes - 2);
+ final IntKeyframe nextKeyframe = (IntKeyframe) mKeyframes.get(mNumKeyframes - 1);
+ int prevValue = prevKeyframe.getIntValue();
+ int nextValue = nextKeyframe.getIntValue();
+ float prevFraction = prevKeyframe.getFraction();
+ float nextFraction = nextKeyframe.getFraction();
+ final TimeInterpolator interpolator = nextKeyframe.getInterpolator();
+ if (interpolator != null) {
+ fraction = interpolator.getInterpolation(fraction);
+ }
+ float intervalFraction = (fraction - prevFraction) / (nextFraction - prevFraction);
+ return mEvaluator == null ?
+ prevValue + (int)(fraction * (nextValue - prevValue)) :
+ ((Number)mEvaluator.evaluate(intervalFraction, prevValue, nextValue)).intValue();
+ }
+ IntKeyframe prevKeyframe = (IntKeyframe) mKeyframes.get(0);
+ for (int i = 1; i < mNumKeyframes; ++i) {
+ IntKeyframe nextKeyframe = (IntKeyframe) mKeyframes.get(i);
+ if (fraction < nextKeyframe.getFraction()) {
+ final TimeInterpolator interpolator = nextKeyframe.getInterpolator();
+ if (interpolator != null) {
+ fraction = interpolator.getInterpolation(fraction);
+ }
+ float intervalFraction = (fraction - prevKeyframe.getFraction()) /
+ (nextKeyframe.getFraction() - prevKeyframe.getFraction());
+ int prevValue = prevKeyframe.getIntValue();
+ int nextValue = nextKeyframe.getIntValue();
+ return mEvaluator == null ?
+ prevValue + (int)(fraction * (nextValue - prevValue)) :
+ ((Number)mEvaluator.evaluate(intervalFraction, prevValue, nextValue)).
+ intValue();
+ }
+ prevKeyframe = nextKeyframe;
+ }
+ // shouldn't get here
+ return ((Number)mKeyframes.get(mNumKeyframes - 1).getValue()).intValue();
+ }
+
+}
+
diff --git a/core/java/android/animation/Keyframe.java b/core/java/android/animation/Keyframe.java
index f9a4f3c..e98719a 100644
--- a/core/java/android/animation/Keyframe.java
+++ b/core/java/android/animation/Keyframe.java
@@ -23,23 +23,27 @@ package android.animation;
* target object will animate between the value at the previous keyframe and the value at the
* next keyframe. Each keyframe also holds an optional {@link TimeInterpolator}
* object, which defines the time interpolation over the intervalue preceding the keyframe.
+ *
+ * <p>The Keyframe class itself is abstract. The type-specific factory methods will return
+ * a subclass of Keyframe specific to the type of value being stored. This is done to improve
+ * performance when dealing with the most common cases (e.g., <code>float</code> and
+ * <code>int</code> values). Other types will fall into a more general Keyframe class that
+ * treats its values as Objects. Unless your animation requires dealing with a custom type
+ * or a data structure that needs to be animated directly (and evaluated using an implementation
+ * of {@link TypeEvaluator}), you should stick to using float and int as animations using those
+ * types have lower runtime overhead than other types.</p>
*/
-public class Keyframe implements Cloneable {
+public abstract class Keyframe implements Cloneable {
/**
* The time at which mValue will hold true.
*/
- private float mFraction;
-
- /**
- * The value of the animation at the time mFraction.
- */
- private Object mValue;
+ float mFraction;
/**
* The type of the value in this Keyframe. This type is determined at construction time,
* based on the type of the <code>value</code> object passed into the constructor.
*/
- private Class mValueType;
+ Class mValueType;
/**
* The optional time interpolator for the interval preceding this keyframe. A null interpolator
@@ -48,23 +52,11 @@ public class Keyframe implements Cloneable {
private TimeInterpolator mInterpolator = null;
/**
- * Private constructor, called from the public constructors with the additional
- * <code>valueType</code> parameter.
- *
- * @param fraction The time, expressed as a value between 0 and 1, representing the fraction
- * of time elapsed of the overall animation duration.
- * @param value The value that the object will animate to as the animation time approaches
- * the time in this keyframe, and the the value animated from as the time passes the time in
- * this keyframe.
- * @param valueType The type of the <code>value</code> object. This is used by the
- * {@link #getValue()} functionm, which is queried by {@link ValueAnimator} to determine
- * the type of {@link TypeEvaluator} to use to interpolate between values.
+ * Flag to indicate whether this keyframe has a valid value. This flag is used when an
+ * animation first starts, to populate placeholder keyframes with real values derived
+ * from the target object.
*/
- private Keyframe(float fraction, Object value, Class valueType) {
- mFraction = fraction;
- mValue = value;
- mValueType = valueType;
- }
+ boolean mHasValue = false;
/**
* Constructs a Keyframe object with the given time and value. The time defines the
@@ -78,28 +70,28 @@ public class Keyframe implements Cloneable {
* the time in this keyframe, and the the value animated from as the time passes the time in
* this keyframe.
*/
- public Keyframe(float fraction, Object value) {
- this(fraction, value, (value != null) ? value.getClass() : Object.class);
+ public static Keyframe ofInt(float fraction, int value) {
+ return new IntKeyframe(fraction, value);
}
/**
- * Constructs a Keyframe object with the given time and float value. The time defines the
+ * Constructs a Keyframe object with the given time. The value at this time will be derived
+ * from the target object when the animation first starts (note that this implies that keyframes
+ * with no initial value must be used as part of an {@link ObjectAnimator}).
+ * The time defines the
* time, as a proportion of an overall animation's duration, at which the value will hold true
* for the animation. The value for the animation between keyframes will be calculated as
* an interpolation between the values at those keyframes.
*
* @param fraction The time, expressed as a value between 0 and 1, representing the fraction
* of time elapsed of the overall animation duration.
- * @param value The value that the object will animate to as the animation time approaches
- * the time in this keyframe, and the the value animated from as the time passes the time in
- * this keyframe.
*/
- public Keyframe(float fraction, Float value) {
- this(fraction, value, Float.class);
+ public static Keyframe ofInt(float fraction) {
+ return new IntKeyframe(fraction);
}
/**
- * Constructs a Keyframe object with the given time and integer value. The time defines the
+ * Constructs a Keyframe object with the given time and value. The time defines the
* time, as a proportion of an overall animation's duration, at which the value will hold true
* for the animation. The value for the animation between keyframes will be calculated as
* an interpolation between the values at those keyframes.
@@ -110,28 +102,28 @@ public class Keyframe implements Cloneable {
* the time in this keyframe, and the the value animated from as the time passes the time in
* this keyframe.
*/
- public Keyframe(float fraction, Integer value) {
- this(fraction, value, Integer.class);
+ public static Keyframe ofFloat(float fraction, float value) {
+ return new FloatKeyframe(fraction, value);
}
/**
- * Constructs a Keyframe object with the given time and double value. The time defines the
+ * Constructs a Keyframe object with the given time. The value at this time will be derived
+ * from the target object when the animation first starts (note that this implies that keyframes
+ * with no initial value must be used as part of an {@link ObjectAnimator}).
+ * The time defines the
* time, as a proportion of an overall animation's duration, at which the value will hold true
* for the animation. The value for the animation between keyframes will be calculated as
* an interpolation between the values at those keyframes.
*
* @param fraction The time, expressed as a value between 0 and 1, representing the fraction
* of time elapsed of the overall animation duration.
- * @param value The value that the object will animate to as the animation time approaches
- * the time in this keyframe, and the the value animated from as the time passes the time in
- * this keyframe.
*/
- public Keyframe(float fraction, Double value) {
- this(fraction, value, Double.class);
+ public static Keyframe ofFloat(float fraction) {
+ return new FloatKeyframe(fraction);
}
/**
- * Constructs a Keyframe object with the given time and integer value. The time defines the
+ * Constructs a Keyframe object with the given time and value. The time defines the
* time, as a proportion of an overall animation's duration, at which the value will hold true
* for the animation. The value for the animation between keyframes will be calculated as
* an interpolation between the values at those keyframes.
@@ -142,40 +134,35 @@ public class Keyframe implements Cloneable {
* the time in this keyframe, and the the value animated from as the time passes the time in
* this keyframe.
*/
- public Keyframe(float fraction, int value) {
- this(fraction, value, int.class);
+ public static Keyframe ofObject(float fraction, Object value) {
+ return new ObjectKeyframe(fraction, value);
}
/**
- * Constructs a Keyframe object with the given time and float value. The time defines the
+ * Constructs a Keyframe object with the given time. The value at this time will be derived
+ * from the target object when the animation first starts (note that this implies that keyframes
+ * with no initial value must be used as part of an {@link ObjectAnimator}).
+ * The time defines the
* time, as a proportion of an overall animation's duration, at which the value will hold true
* for the animation. The value for the animation between keyframes will be calculated as
* an interpolation between the values at those keyframes.
*
* @param fraction The time, expressed as a value between 0 and 1, representing the fraction
* of time elapsed of the overall animation duration.
- * @param value The value that the object will animate to as the animation time approaches
- * the time in this keyframe, and the the value animated from as the time passes the time in
- * this keyframe.
*/
- public Keyframe(float fraction, float value) {
- this(fraction, value, float.class);
+ public static Keyframe ofObject(float fraction) {
+ return new ObjectKeyframe(fraction, null);
}
/**
- * Constructs a Keyframe object with the given time and double value. The time defines the
- * time, as a proportion of an overall animation's duration, at which the value will hold true
- * for the animation. The value for the animation between keyframes will be calculated as
- * an interpolation between the values at those keyframes.
+ * Indicates whether this keyframe has a valid value. This method is called internally when
+ * an {@link ObjectAnimator} first starts; keyframes without values are assigned values at
+ * that time by deriving the value for the property from the target object.
*
- * @param fraction The time, expressed as a value between 0 and 1, representing the fraction
- * of time elapsed of the overall animation duration.
- * @param value The value that the object will animate to as the animation time approaches
- * the time in this keyframe, and the the value animated from as the time passes the time in
- * this keyframe.
+ * @return boolean Whether this object has a value assigned.
*/
- public Keyframe(float fraction, double value) {
- this(fraction, value, double.class);
+ public boolean hasValue() {
+ return mHasValue;
}
/**
@@ -183,18 +170,14 @@ public class Keyframe implements Cloneable {
*
* @return The value for this Keyframe.
*/
- public Object getValue() {
- return mValue;
- }
+ public abstract Object getValue();
/**
* Sets the value for this Keyframe.
*
* @param value value for this Keyframe.
*/
- public void setValue(Object value) {
- mValue = value;
- }
+ public abstract void setValue(Object value);
/**
* Gets the time for this keyframe, as a fraction of the overall animation duration.
@@ -248,9 +231,128 @@ public class Keyframe implements Cloneable {
}
@Override
- public Keyframe clone() {
- Keyframe kfClone = new Keyframe(mFraction, mValue, mValueType);
- kfClone.setInterpolator(mInterpolator);
- return kfClone;
+ public abstract Keyframe clone();
+
+ /**
+ * This internal subclass is used for all types which are not int or float.
+ */
+ static class ObjectKeyframe extends Keyframe {
+
+ /**
+ * The value of the animation at the time mFraction.
+ */
+ Object mValue;
+
+ ObjectKeyframe(float fraction, Object value) {
+ mFraction = fraction;
+ mValue = value;
+ mHasValue = (value != null);
+ mValueType = mHasValue ? value.getClass() : Object.class;
+ }
+
+ public Object getValue() {
+ return mValue;
+ }
+
+ public void setValue(Object value) {
+ mValue = value;
+ mHasValue = (value != null);
+ }
+
+ @Override
+ public ObjectKeyframe clone() {
+ ObjectKeyframe kfClone = new ObjectKeyframe(getFraction(), mValue);
+ kfClone.setInterpolator(getInterpolator());
+ return kfClone;
+ }
+ }
+
+ /**
+ * Internal subclass used when the keyframe value is of type int.
+ */
+ static class IntKeyframe extends Keyframe {
+
+ /**
+ * The value of the animation at the time mFraction.
+ */
+ int mValue;
+
+ IntKeyframe(float fraction, int value) {
+ mFraction = fraction;
+ mValue = value;
+ mValueType = int.class;
+ mHasValue = true;
+ }
+
+ IntKeyframe(float fraction) {
+ mFraction = fraction;
+ mValueType = int.class;
+ }
+
+ public int getIntValue() {
+ return mValue;
+ }
+
+ public Object getValue() {
+ return mValue;
+ }
+
+ public void setValue(Object value) {
+ if (value != null && value.getClass() == Integer.class) {
+ mValue = ((Integer)value).intValue();
+ mHasValue = true;
+ }
+ }
+
+ @Override
+ public IntKeyframe clone() {
+ IntKeyframe kfClone = new IntKeyframe(getFraction(), mValue);
+ kfClone.setInterpolator(getInterpolator());
+ return kfClone;
+ }
+ }
+
+ /**
+ * Internal subclass used when the keyframe value is of type float.
+ */
+ static class FloatKeyframe extends Keyframe {
+ /**
+ * The value of the animation at the time mFraction.
+ */
+ float mValue;
+
+ FloatKeyframe(float fraction, float value) {
+ mFraction = fraction;
+ mValue = value;
+ mValueType = float.class;
+ mHasValue = true;
+ }
+
+ FloatKeyframe(float fraction) {
+ mFraction = fraction;
+ mValueType = float.class;
+ }
+
+ public float getFloatValue() {
+ return mValue;
+ }
+
+ public Object getValue() {
+ return mValue;
+ }
+
+ public void setValue(Object value) {
+ if (value != null && value.getClass() == Float.class) {
+ mValue = ((Float)value).floatValue();
+ mHasValue = true;
+ }
+ }
+
+ @Override
+ public FloatKeyframe clone() {
+ FloatKeyframe kfClone = new FloatKeyframe(getFraction(), mValue);
+ kfClone.setInterpolator(getInterpolator());
+ return kfClone;
+ }
}
}
diff --git a/core/java/android/animation/KeyframeSet.java b/core/java/android/animation/KeyframeSet.java
index 2242462..fa61b71 100644
--- a/core/java/android/animation/KeyframeSet.java
+++ b/core/java/android/animation/KeyframeSet.java
@@ -18,6 +18,9 @@ package android.animation;
import java.util.ArrayList;
import java.util.Arrays;
+import android.animation.Keyframe.IntKeyframe;
+import android.animation.Keyframe.FloatKeyframe;
+import android.animation.Keyframe.ObjectKeyframe;
/**
* This class holds a collection of Keyframe objects and is called by ValueAnimator to calculate
@@ -26,12 +29,14 @@ import java.util.Arrays;
*/
class KeyframeSet {
- private int mNumKeyframes;
+ int mNumKeyframes;
Keyframe mFirstKeyframe;
Keyframe mLastKeyframe;
TimeInterpolator mInterpolator; // only used in the 2-keyframe case
ArrayList<Keyframe> mKeyframes; // only used when there are not 2 keyframes
+ TypeEvaluator mEvaluator;
+
public KeyframeSet(Keyframe... keyframes) {
mNumKeyframes = keyframes.length;
@@ -44,80 +49,106 @@ class KeyframeSet {
public static KeyframeSet ofInt(int... values) {
int numKeyframes = values.length;
- Keyframe keyframes[] = new Keyframe[Math.max(numKeyframes,2)];
+ IntKeyframe keyframes[] = new IntKeyframe[Math.max(numKeyframes,2)];
if (numKeyframes == 1) {
- keyframes[0] = new Keyframe(0f, (Object) null);
- keyframes[1] = new Keyframe(1f, values[0]);
+ keyframes[0] = (IntKeyframe) Keyframe.ofInt(0f);
+ keyframes[1] = (IntKeyframe) Keyframe.ofInt(1f, values[0]);
} else {
- keyframes[0] = new Keyframe(0f, values[0]);
+ keyframes[0] = (IntKeyframe) Keyframe.ofInt(0f, values[0]);
for (int i = 1; i < numKeyframes; ++i) {
- keyframes[i] = new Keyframe((float) i / (numKeyframes - 1), values[i]);
+ keyframes[i] = (IntKeyframe) Keyframe.ofInt((float) i / (numKeyframes - 1), values[i]);
}
}
- return new KeyframeSet(keyframes);
+ return new IntKeyframeSet(keyframes);
}
public static KeyframeSet ofFloat(float... values) {
int numKeyframes = values.length;
- Keyframe keyframes[] = new Keyframe[Math.max(numKeyframes,2)];
+ FloatKeyframe keyframes[] = new FloatKeyframe[Math.max(numKeyframes,2)];
if (numKeyframes == 1) {
- keyframes[0] = new Keyframe(0f, (Object) null);
- keyframes[1] = new Keyframe(1f, values[0]);
+ keyframes[0] = (FloatKeyframe) Keyframe.ofFloat(0f);
+ keyframes[1] = (FloatKeyframe) Keyframe.ofFloat(1f, values[0]);
} else {
- keyframes[0] = new Keyframe(0f, values[0]);
+ keyframes[0] = (FloatKeyframe) Keyframe.ofFloat(0f, values[0]);
for (int i = 1; i < numKeyframes; ++i) {
- keyframes[i] = new Keyframe((float) i / (numKeyframes - 1), values[i]);
+ keyframes[i] = (FloatKeyframe) Keyframe.ofFloat((float) i / (numKeyframes - 1), values[i]);
}
}
- return new KeyframeSet(keyframes);
+ return new FloatKeyframeSet(keyframes);
}
- public static KeyframeSet ofDouble(double... values) {
- int numKeyframes = values.length;
- Keyframe keyframes[] = new Keyframe[Math.max(numKeyframes,2)];
- if (numKeyframes == 1) {
- keyframes[0] = new Keyframe(0f, (Object) null);
- keyframes[1] = new Keyframe(1f, values[0]);
- } else {
- keyframes[0] = new Keyframe(0f, values[0]);
- for (int i = 1; i < numKeyframes; ++i) {
- keyframes[i] = new Keyframe((float) i / (numKeyframes - 1), values[i]);
+ public static KeyframeSet ofKeyframe(Keyframe... keyframes) {
+ // if all keyframes of same primitive type, create the appropriate KeyframeSet
+ int numKeyframes = keyframes.length;
+ boolean hasFloat = false;
+ boolean hasInt = false;
+ boolean hasOther = false;
+ for (int i = 0; i < numKeyframes; ++i) {
+ if (keyframes[i] instanceof FloatKeyframe) {
+ hasFloat = true;
+ } else if (keyframes[i] instanceof IntKeyframe) {
+ hasInt = true;
+ } else {
+ hasOther = true;
}
}
- return new KeyframeSet(keyframes);
- }
-
- public static KeyframeSet ofLong(long... values) {
- int numKeyframes = values.length;
- Keyframe keyframes[] = new Keyframe[Math.max(numKeyframes,2)];
- if (numKeyframes == 1) {
- keyframes[0] = new Keyframe(0f, (Object) null);
- keyframes[1] = new Keyframe(1f, values[0]);
- } else {
- keyframes[0] = new Keyframe(0f, values[0]);
- for (int i = 1; i < numKeyframes; ++i) {
- keyframes[i] = new Keyframe((float) i / (numKeyframes - 1), values[i]);
+ if (hasFloat && !hasInt && !hasOther) {
+ FloatKeyframe floatKeyframes[] = new FloatKeyframe[numKeyframes];
+ for (int i = 0; i < numKeyframes; ++i) {
+ floatKeyframes[i] = (FloatKeyframe) keyframes[i];
+ }
+ return new FloatKeyframeSet(floatKeyframes);
+ } else if (hasInt && !hasFloat && !hasOther) {
+ IntKeyframe intKeyframes[] = new IntKeyframe[numKeyframes];
+ for (int i = 0; i < numKeyframes; ++i) {
+ intKeyframes[i] = (IntKeyframe) keyframes[i];
}
+ return new IntKeyframeSet(intKeyframes);
+ } else {
+ return new KeyframeSet(keyframes);
}
- return new KeyframeSet(keyframes);
}
public static KeyframeSet ofObject(Object... values) {
int numKeyframes = values.length;
- Keyframe keyframes[] = new Keyframe[Math.max(numKeyframes,2)];
+ ObjectKeyframe keyframes[] = new ObjectKeyframe[Math.max(numKeyframes,2)];
if (numKeyframes == 1) {
- keyframes[0] = new Keyframe(0f, (Object) null);
- keyframes[1] = new Keyframe(1f, values[0]);
+ keyframes[0] = (ObjectKeyframe) Keyframe.ofObject(0f);
+ keyframes[1] = (ObjectKeyframe) Keyframe.ofObject(1f, values[0]);
} else {
- keyframes[0] = new Keyframe(0f, values[0]);
+ keyframes[0] = (ObjectKeyframe) Keyframe.ofObject(0f, values[0]);
for (int i = 1; i < numKeyframes; ++i) {
- keyframes[i] = new Keyframe((float) i / (numKeyframes - 1), values[i]);
+ keyframes[i] = (ObjectKeyframe) Keyframe.ofObject((float) i / (numKeyframes - 1), values[i]);
}
}
return new KeyframeSet(keyframes);
}
/**
+ * Sets the TypeEvaluator to be used when calculating animated values. This object
+ * is required only for KeyframeSets that are not either IntKeyframeSet or FloatKeyframeSet,
+ * both of which assume their own evaluator to speed up calculations with those primitive
+ * types.
+ *
+ * @param evaluator The TypeEvaluator to be used to calculate animated values.
+ */
+ public void setEvaluator(TypeEvaluator evaluator) {
+ mEvaluator = evaluator;
+ }
+
+ @Override
+ public KeyframeSet clone() {
+ ArrayList<Keyframe> keyframes = mKeyframes;
+ int numKeyframes = mKeyframes.size();
+ Keyframe[] newKeyframes = new Keyframe[numKeyframes];
+ for (int i = 0; i < numKeyframes; ++i) {
+ newKeyframes[i] = keyframes.get(i).clone();
+ }
+ KeyframeSet newSet = new KeyframeSet(newKeyframes);
+ return newSet;
+ }
+
+ /**
* Gets the animated value, given the elapsed fraction of the animation (interpolated by the
* animation's interpolator) and the evaluator used to calculate in-between values. This
* function maps the input fraction to the appropriate keyframe interval and a fraction
@@ -127,20 +158,18 @@ class KeyframeSet {
* just using the two keyframes at the appropriate end when the value is outside those bounds.
*
* @param fraction The elapsed fraction of the animation
- * @param evaluator The type evaluator to use when calculating the interpolated values.
* @return The animated value.
*/
- public Object getValue(float fraction, TypeEvaluator evaluator) {
+ public Object getValue(float fraction) {
// Special-case optimization for the common case of only two keyframes
if (mNumKeyframes == 2) {
if (mInterpolator != null) {
fraction = mInterpolator.getInterpolation(fraction);
}
- return evaluator.evaluate(fraction, mFirstKeyframe.getValue(),
+ return mEvaluator.evaluate(fraction, mFirstKeyframe.getValue(),
mLastKeyframe.getValue());
}
-
if (fraction <= 0f) {
final Keyframe nextKeyframe = mKeyframes.get(1);
final TimeInterpolator interpolator = nextKeyframe.getInterpolator();
@@ -150,7 +179,7 @@ class KeyframeSet {
final float prevFraction = mFirstKeyframe.getFraction();
float intervalFraction = (fraction - prevFraction) /
(nextKeyframe.getFraction() - prevFraction);
- return evaluator.evaluate(intervalFraction, mFirstKeyframe.getValue(),
+ return mEvaluator.evaluate(intervalFraction, mFirstKeyframe.getValue(),
nextKeyframe.getValue());
} else if (fraction >= 1f) {
final Keyframe prevKeyframe = mKeyframes.get(mNumKeyframes - 2);
@@ -161,7 +190,7 @@ class KeyframeSet {
final float prevFraction = prevKeyframe.getFraction();
float intervalFraction = (fraction - prevFraction) /
(mLastKeyframe.getFraction() - prevFraction);
- return evaluator.evaluate(intervalFraction, prevKeyframe.getValue(),
+ return mEvaluator.evaluate(intervalFraction, prevKeyframe.getValue(),
mLastKeyframe.getValue());
}
Keyframe prevKeyframe = mFirstKeyframe;
@@ -175,7 +204,7 @@ class KeyframeSet {
final float prevFraction = prevKeyframe.getFraction();
float intervalFraction = (fraction - prevFraction) /
(nextKeyframe.getFraction() - prevFraction);
- return evaluator.evaluate(intervalFraction, prevKeyframe.getValue(),
+ return mEvaluator.evaluate(intervalFraction, prevKeyframe.getValue(),
nextKeyframe.getValue());
}
prevKeyframe = nextKeyframe;
diff --git a/core/java/android/animation/ObjectAnimator.java b/core/java/android/animation/ObjectAnimator.java
index 5b8c91d..c898ae3 100644
--- a/core/java/android/animation/ObjectAnimator.java
+++ b/core/java/android/animation/ObjectAnimator.java
@@ -175,48 +175,6 @@ public final class ObjectAnimator extends ValueAnimator {
}
/**
- * Constructs and returns an ObjectAnimator that animates between long values. A single
- * value implies that that value is the one being animated to. However, this is not typically
- * useful in a ValueAnimator object because there is no way for the object to determine the
- * starting value for the animation (unlike ObjectAnimator, which can derive that value
- * from the target object and property being animated). Therefore, there should typically
- * be two or more values.
- *
- * @param target The object whose property is to be animated. This object should
- * have a public method on it called <code>setName()</code>, where <code>name</code> is
- * the value of the <code>propertyName</code> parameter.
- * @param propertyName The name of the property being animated.
- * @param values A set of values that the animation will animate between over time.
- * @return A ValueAnimator object that is set up to animate between the given values.
- */
- public static ObjectAnimator ofLong(Object target, String propertyName, long... values) {
- ObjectAnimator anim = new ObjectAnimator(target, propertyName);
- anim.setLongValues(values);
- return anim;
- }
-
- /**
- * Constructs and returns an ObjectAnimator that animates between double values. A single
- * value implies that that value is the one being animated to. However, this is not typically
- * useful in a ValueAnimator object because there is no way for the object to determine the
- * starting value for the animation (unlike ObjectAnimator, which can derive that value
- * from the target object and property being animated). Therefore, there should typically
- * be two or more values.
- *
- * @param target The object whose property is to be animated. This object should
- * have a public method on it called <code>setName()</code>, where <code>name</code> is
- * the value of the <code>propertyName</code> parameter.
- * @param propertyName The name of the property being animated.
- * @param values A set of values that the animation will animate between over time.
- * @return A ValueAnimator object that is set up to animate between the given values.
- */
- public static ObjectAnimator ofDouble(Object target, String propertyName, double... values) {
- ObjectAnimator anim = new ObjectAnimator(target, propertyName);
- anim.setDoubleValues(values);
- return anim;
- }
-
- /**
* A constructor that takes <code>PropertyValueHolder</code> values. This constructor should
* be used when animating several properties at once with the same ObjectAnimator, since
* PropertyValuesHolder allows you to associate a set of animation values with a property
@@ -287,28 +245,6 @@ public final class ObjectAnimator extends ValueAnimator {
}
@Override
- public void setDoubleValues(double... values) {
- if (mValues == null || mValues.length == 0) {
- // No values yet - this animator is being constructed piecemeal. Init the values with
- // whatever the current propertyName is
- setValues(PropertyValuesHolder.ofDouble(mPropertyName, values));
- } else {
- super.setDoubleValues(values);
- }
- }
-
- @Override
- public void setLongValues(long... values) {
- if (mValues == null || mValues.length == 0) {
- // No values yet - this animator is being constructed piecemeal. Init the values with
- // whatever the current propertyName is
- setValues(PropertyValuesHolder.ofLong(mPropertyName, values));
- } else {
- super.setLongValues(values);
- }
- }
-
- @Override
public void setObjectValues(Object... values) {
if (mValues == null || mValues.length == 0) {
// No values yet - this animator is being constructed piecemeal. Init the values with
diff --git a/core/java/android/animation/PropertyValuesHolder.java b/core/java/android/animation/PropertyValuesHolder.java
index 0f759f1..39754b0 100644
--- a/core/java/android/animation/PropertyValuesHolder.java
+++ b/core/java/android/animation/PropertyValuesHolder.java
@@ -17,6 +17,8 @@
package android.animation;
import android.util.Log;
+import android.animation.Keyframe.IntKeyframe;
+import android.animation.Keyframe.FloatKeyframe;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
@@ -45,7 +47,7 @@ public class PropertyValuesHolder implements Cloneable {
* property can be manually set via setSetter(). Otherwise, it is automatically
* derived when the animation starts in setupSetterAndGetter() if using ObjectAnimator.
*/
- private Method mSetter = null;
+ Method mSetter = null;
/**
* The getter function, if needed. ObjectAnimator hands off this functionality to
@@ -60,12 +62,12 @@ public class PropertyValuesHolder implements Cloneable {
* The type of values supplied. This information is used both in deriving the setter/getter
* functions and in deriving the type of TypeEvaluator.
*/
- private Class mValueType;
+ Class mValueType;
/**
* The set of keyframes (time/value pairs) that define this animation.
*/
- private KeyframeSet mKeyframeSet = null;
+ KeyframeSet mKeyframeSet = null;
// type evaluators for the three primitive types handled by this implementation
@@ -100,7 +102,7 @@ public class PropertyValuesHolder implements Cloneable {
private ReentrantReadWriteLock propertyMapLock = new ReentrantReadWriteLock();
// Used to pass single value to varargs parameter in setter invocation
- private Object[] mTmpValueArray = new Object[1];
+ Object[] mTmpValueArray = new Object[1];
/**
* The type evaluator used to calculate the animated values. This evaluator is determined
@@ -133,8 +135,7 @@ public class PropertyValuesHolder implements Cloneable {
* @return PropertyValuesHolder The constructed PropertyValuesHolder object.
*/
public static PropertyValuesHolder ofInt(String propertyName, int... values) {
- PropertyValuesHolder pvh = new PropertyValuesHolder(propertyName);
- pvh.setIntValues(values);
+ PropertyValuesHolder pvh = new IntPropertyValuesHolder(propertyName, values);
return pvh;
}
@@ -146,34 +147,7 @@ public class PropertyValuesHolder implements Cloneable {
* @return PropertyValuesHolder The constructed PropertyValuesHolder object.
*/
public static PropertyValuesHolder ofFloat(String propertyName, float... values) {
- PropertyValuesHolder pvh = new PropertyValuesHolder(propertyName);
- pvh.setFloatValues(values);
- return pvh;
- }
-
- /**
- * Constructs and returns a PropertyValuesHolder with a given property name and
- * set of double values.
- * @param propertyName The name of the property being animated.
- * @param values The values that the named property will animate between.
- * @return PropertyValuesHolder The constructed PropertyValuesHolder object.
- */
- public static PropertyValuesHolder ofDouble(String propertyName, double... values) {
- PropertyValuesHolder pvh = new PropertyValuesHolder(propertyName);
- pvh.setDoubleValues(values);
- return pvh;
- }
-
- /**
- * Constructs and returns a PropertyValuesHolder with a given property name and
- * set of long values.
- * @param propertyName The name of the property being animated.
- * @param values The values that the named property will animate between.
- * @return PropertyValuesHolder The constructed PropertyValuesHolder object.
- */
- public static PropertyValuesHolder ofLong(String propertyName, long... values) {
- PropertyValuesHolder pvh = new PropertyValuesHolder(propertyName);
- pvh.setLongValues(values);
+ PropertyValuesHolder pvh = new FloatPropertyValuesHolder(propertyName, values);
return pvh;
}
@@ -218,9 +192,18 @@ public class PropertyValuesHolder implements Cloneable {
* @param values The set of values to animate between.
*/
public static PropertyValuesHolder ofKeyframe(String propertyName, Keyframe... values) {
- PropertyValuesHolder pvh = new PropertyValuesHolder(propertyName);
- pvh.setKeyframes(values);
- return pvh;
+ KeyframeSet keyframeSet = KeyframeSet.ofKeyframe(values);
+ if (keyframeSet instanceof IntKeyframeSet) {
+ return new IntPropertyValuesHolder(propertyName, (IntKeyframeSet) keyframeSet);
+ } else if (keyframeSet instanceof FloatKeyframeSet) {
+ return new FloatPropertyValuesHolder(propertyName, (FloatKeyframeSet) keyframeSet);
+ }
+ else {
+ PropertyValuesHolder pvh = new PropertyValuesHolder(propertyName);
+ pvh.mKeyframeSet = keyframeSet;
+ pvh.mValueType = ((Keyframe)values[0]).getType();
+ return pvh;
+ }
}
/**
@@ -262,44 +245,6 @@ public class PropertyValuesHolder implements Cloneable {
}
/**
- * Set the animated values for this object to this set of doubles.
- * If there is only one value, it is assumed to be the end value of an animation,
- * and an initial value will be derived, if possible, by calling a getter function
- * on the object. Also, if any value is null, the value will be filled in when the animation
- * starts in the same way. This mechanism of automatically getting null values only works
- * if the PropertyValuesHolder object is used in conjunction
- * {@link ObjectAnimator}, and with a getter function either
- * derived automatically from <code>propertyName</code> or set explicitly via
- * {@link #setGetter(java.lang.reflect.Method)}, since otherwise PropertyValuesHolder has
- * no way of determining what the value should be.
- *
- * @param values One or more values that the animation will animate between.
- */
- public void setDoubleValues(double... values) {
- mValueType = double.class;
- mKeyframeSet = KeyframeSet.ofDouble(values);
- }
-
- /**
- * Set the animated values for this object to this set of longs.
- * If there is only one value, it is assumed to be the end value of an animation,
- * and an initial value will be derived, if possible, by calling a getter function
- * on the object. Also, if any value is null, the value will be filled in when the animation
- * starts in the same way. This mechanism of automatically getting null values only works
- * if the PropertyValuesHolder object is used in conjunction
- * {@link ObjectAnimator}, and with a getter function either
- * derived automatically from <code>propertyName</code> or set explicitly via
- * {@link #setGetter(java.lang.reflect.Method)}, since otherwise PropertyValuesHolder has
- * no way of determining what the value should be.
- *
- * @param values One or more values that the animation will animate between.
- */
- public void setLongValues(long... values) {
- mValueType = long.class;
- mKeyframeSet = KeyframeSet.ofLong(values);
- }
-
- /**
* Set the animated values for this object to this set of Keyframes.
*
* @param values One or more values that the animation will animate between.
@@ -466,7 +411,7 @@ public class PropertyValuesHolder implements Cloneable {
setupSetter(targetClass);
}
for (Keyframe kf : mKeyframeSet.mKeyframes) {
- if (kf.getValue() == null) {
+ if (!kf.hasValue()) {
if (mGetter == null) {
setupGetter(targetClass);
}
@@ -528,14 +473,18 @@ public class PropertyValuesHolder implements Cloneable {
@Override
public PropertyValuesHolder clone() {
- ArrayList<Keyframe> keyframes = mKeyframeSet.mKeyframes;
- int numKeyframes = mKeyframeSet.mKeyframes.size();
- Keyframe[] newKeyframes = new Keyframe[numKeyframes];
- for (int i = 0; i < numKeyframes; ++i) {
- newKeyframes[i] = keyframes.get(i).clone();
+ try {
+ PropertyValuesHolder newPVH = (PropertyValuesHolder) super.clone();
+ newPVH.mPropertyName = mPropertyName;
+ newPVH.mKeyframeSet = mKeyframeSet.clone();
+ newPVH.mEvaluator = mEvaluator;
+ return newPVH;
+ } catch (CloneNotSupportedException e) {
+ // won't reach here
+ return null;
}
- return PropertyValuesHolder.ofKeyframe(mPropertyName, newKeyframes);
}
+
/**
* Internal function to set the value on the target object, using the setter set up
* earlier on this PropertyValuesHolder object. This function is called by ObjectAnimator
@@ -546,7 +495,7 @@ public class PropertyValuesHolder implements Cloneable {
void setAnimatedValue(Object target) {
if (mSetter != null) {
try {
- mTmpValueArray[0] = mAnimatedValue;
+ mTmpValueArray[0] = getAnimatedValue();
mSetter.invoke(target, mTmpValueArray);
} catch (InvocationTargetException e) {
Log.e("PropertyValuesHolder", e.toString());
@@ -562,9 +511,16 @@ public class PropertyValuesHolder implements Cloneable {
*/
void init() {
if (mEvaluator == null) {
- mEvaluator = (mValueType == int.class || mValueType == Integer.class) ? sIntEvaluator :
- (mValueType == double.class || mValueType == Double.class) ? sDoubleEvaluator :
- sFloatEvaluator;
+ // We already handle int, float, long, double automatically, but not their Object
+ // equivalents
+ mEvaluator = (mValueType == Integer.class) ? sIntEvaluator :
+ (mValueType == Float.class) ? sFloatEvaluator :
+ null;
+ }
+ if (mEvaluator != null) {
+ // KeyframeSet knows how to evaluate the common types - only give it a custom
+ // evaulator if one has been set on this class
+ mKeyframeSet.setEvaluator(mEvaluator);
}
}
@@ -578,8 +534,9 @@ public class PropertyValuesHolder implements Cloneable {
* and Integer) are correctly interpolated; all other types require setting a TypeEvaluator.
* @param evaluator
*/
- public void setEvaluator(TypeEvaluator evaluator) {
+ public void setEvaluator(TypeEvaluator evaluator) {
mEvaluator = evaluator;
+ mKeyframeSet.setEvaluator(evaluator);
}
/**
@@ -587,11 +544,9 @@ public class PropertyValuesHolder implements Cloneable {
* this PropertyValuesHolder object. This function is called by ValueAnimator.animateValue().
*
* @param fraction The elapsed, interpolated fraction of the animation.
- * @return The calculated value at this point in the animation.
*/
- Object calculateValue(float fraction) {
- mAnimatedValue = mKeyframeSet.getValue(fraction, mEvaluator);
- return mAnimatedValue;
+ void calculateValue(float fraction) {
+ mAnimatedValue = mKeyframeSet.getValue(fraction);
}
/**
@@ -694,4 +649,119 @@ public class PropertyValuesHolder implements Cloneable {
Object getAnimatedValue() {
return mAnimatedValue;
}
+
+ static class IntPropertyValuesHolder extends PropertyValuesHolder {
+
+ IntKeyframeSet mIntKeyframeSet;
+ int mIntAnimatedValue;
+
+ public IntPropertyValuesHolder(String propertyName, IntKeyframeSet keyframeSet) {
+ super(propertyName);
+ mValueType = int.class;
+ mKeyframeSet = keyframeSet;
+ mIntKeyframeSet = (IntKeyframeSet) mKeyframeSet;
+ }
+
+ public IntPropertyValuesHolder(String propertyName, int... values) {
+ super(propertyName);
+ setIntValues(values);
+ mIntKeyframeSet = (IntKeyframeSet) mKeyframeSet;
+ }
+
+ @Override
+ void calculateValue(float fraction) {
+ mIntAnimatedValue = mIntKeyframeSet.getIntValue(fraction);
+ }
+
+ @Override
+ Object getAnimatedValue() {
+ return mIntAnimatedValue;
+ }
+
+ @Override
+ public IntPropertyValuesHolder clone() {
+ IntPropertyValuesHolder newPVH = (IntPropertyValuesHolder) super.clone();
+ newPVH.mIntKeyframeSet = (IntKeyframeSet) newPVH.mKeyframeSet;
+ return newPVH;
+ }
+
+ /**
+ * Internal function to set the value on the target object, using the setter set up
+ * earlier on this PropertyValuesHolder object. This function is called by ObjectAnimator
+ * to handle turning the value calculated by ValueAnimator into a value set on the object
+ * according to the name of the property.
+ * @param target The target object on which the value is set
+ */
+ @Override
+ void setAnimatedValue(Object target) {
+ if (mSetter != null) {
+ try {
+ mTmpValueArray[0] = mIntAnimatedValue;
+ mSetter.invoke(target, mTmpValueArray);
+ } catch (InvocationTargetException e) {
+ Log.e("PropertyValuesHolder", e.toString());
+ } catch (IllegalAccessException e) {
+ Log.e("PropertyValuesHolder", e.toString());
+ }
+ }
+ }
+ }
+
+ static class FloatPropertyValuesHolder extends PropertyValuesHolder {
+
+ FloatKeyframeSet mFloatKeyframeSet;
+ float mFloatAnimatedValue;
+
+ public FloatPropertyValuesHolder(String propertyName, FloatKeyframeSet keyframeSet) {
+ super(propertyName);
+ mValueType = float.class;
+ mKeyframeSet = keyframeSet;
+ mFloatKeyframeSet = (FloatKeyframeSet) mKeyframeSet;
+ }
+
+ public FloatPropertyValuesHolder(String propertyName, float... values) {
+ super(propertyName);
+ setFloatValues(values);
+ mFloatKeyframeSet = (FloatKeyframeSet) mKeyframeSet;
+ }
+
+ @Override
+ void calculateValue(float fraction) {
+ mFloatAnimatedValue = mFloatKeyframeSet.getFloatValue(fraction);
+ }
+
+ @Override
+ Object getAnimatedValue() {
+ return mFloatAnimatedValue;
+ }
+
+ @Override
+ public FloatPropertyValuesHolder clone() {
+ FloatPropertyValuesHolder newPVH = (FloatPropertyValuesHolder) super.clone();
+ newPVH.mFloatKeyframeSet = (FloatKeyframeSet) newPVH.mKeyframeSet;
+ return newPVH;
+ }
+
+ /**
+ * Internal function to set the value on the target object, using the setter set up
+ * earlier on this PropertyValuesHolder object. This function is called by ObjectAnimator
+ * to handle turning the value calculated by ValueAnimator into a value set on the object
+ * according to the name of the property.
+ * @param target The target object on which the value is set
+ */
+ @Override
+ void setAnimatedValue(Object target) {
+ if (mSetter != null) {
+ try {
+ mTmpValueArray[0] = mFloatAnimatedValue;
+ mSetter.invoke(target, mTmpValueArray);
+ } catch (InvocationTargetException e) {
+ Log.e("PropertyValuesHolder", e.toString());
+ } catch (IllegalAccessException e) {
+ Log.e("PropertyValuesHolder", e.toString());
+ }
+ }
+ }
+
+ }
} \ No newline at end of file
diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java
index a0b70b5..b021e75 100755
--- a/core/java/android/animation/ValueAnimator.java
+++ b/core/java/android/animation/ValueAnimator.java
@@ -297,40 +297,6 @@ public class ValueAnimator extends Animator {
}
/**
- * Constructs and returns a ValueAnimator that animates between double values. A single
- * value implies that that value is the one being animated to. However, this is not typically
- * useful in a ValueAnimator object because there is no way for the object to determine the
- * starting value for the animation (unlike ObjectAnimator, which can derive that value
- * from the target object and property being animated). Therefore, there should typically
- * be two or more values.
- *
- * @param values A set of values that the animation will animate between over time.
- * @return A ValueAnimator object that is set up to animate between the given values.
- */
- public static ValueAnimator ofDouble(double... values) {
- ValueAnimator anim = new ValueAnimator();
- anim.setDoubleValues(values);
- return anim;
- }
-
- /**
- * Constructs and returns a ValueAnimator that animates between long values. A single
- * value implies that that value is the one being animated to. However, this is not typically
- * useful in a ValueAnimator object because there is no way for the object to determine the
- * starting value for the animation (unlike ObjectAnimator, which can derive that value
- * from the target object and property being animated). Therefore, there should typically
- * be two or more values.
- *
- * @param values A set of values that the animation will animate between over time.
- * @return A ValueAnimator object that is set up to animate between the given values.
- */
- public static ValueAnimator ofLong(long... values) {
- ValueAnimator anim = new ValueAnimator();
- anim.setLongValues(values);
- return anim;
- }
-
- /**
* Constructs and returns a ValueAnimator that animates between the values
* specified in the PropertyValuesHolder objects.
*
@@ -425,62 +391,6 @@ public class ValueAnimator extends Animator {
}
/**
- * Sets long values that will be animated between. A single
- * value implies that that value is the one being animated to. However, this is not typically
- * useful in a ValueAnimator object because there is no way for the object to determine the
- * starting value for the animation (unlike ObjectAnimator, which can derive that value
- * from the target object and property being animated). Therefore, there should typically
- * be two or more values.
- *
- * <p>If there are already multiple sets of values defined for this ValueAnimator via more
- * than one PropertyValuesHolder object, this method will set the values for the first
- * of those objects.</p>
- *
- * @param values A set of values that the animation will animate between over time.
- */
- public void setLongValues(long... values) {
- if (values == null || values.length == 0) {
- return;
- }
- if (mValues == null || mValues.length == 0) {
- setValues(new PropertyValuesHolder[]{PropertyValuesHolder.ofLong("", values)});
- } else {
- PropertyValuesHolder valuesHolder = mValues[0];
- valuesHolder.setLongValues(values);
- }
- // New property/values/target should cause re-initialization prior to starting
- mInitialized = false;
- }
-
- /**
- * Sets double values that will be animated between. A single
- * value implies that that value is the one being animated to. However, this is not typically
- * useful in a ValueAnimator object because there is no way for the object to determine the
- * starting value for the animation (unlike ObjectAnimator, which can derive that value
- * from the target object and property being animated). Therefore, there should typically
- * be two or more values.
- *
- * <p>If there are already multiple sets of values defined for this ValueAnimator via more
- * than one PropertyValuesHolder object, this method will set the values for the first
- * of those objects.</p>
- *
- * @param values A set of values that the animation will animate between over time.
- */
- public void setDoubleValues(double... values) {
- if (values == null || values.length == 0) {
- return;
- }
- if (mValues == null || mValues.length == 0) {
- setValues(new PropertyValuesHolder[]{PropertyValuesHolder.ofDouble("", values)});
- } else {
- PropertyValuesHolder valuesHolder = mValues[0];
- valuesHolder.setDoubleValues(values);
- }
- // New property/values/target should cause re-initialization prior to starting
- mInitialized = false;
- }
-
- /**
* Sets the values to animate between for this animation. A single
* value implies that that value is the one being animated to. However, this is not typically
* useful in a ValueAnimator object because there is no way for the object to determine the
@@ -968,8 +878,9 @@ public class ValueAnimator extends Animator {
if (mListeners != null) {
ArrayList<AnimatorListener> tmpListeners =
(ArrayList<AnimatorListener>) mListeners.clone();
- for (AnimatorListener listener : tmpListeners) {
- listener.onAnimationStart(this);
+ int numListeners = tmpListeners.size();
+ for (int i = 0; i < numListeners; ++i) {
+ tmpListeners.get(i).onAnimationStart(this);
}
}
// This sets the initial value of the animation, prior to actually starting it running
@@ -1059,8 +970,9 @@ public class ValueAnimator extends Animator {
if (mListeners != null) {
ArrayList<AnimatorListener> tmpListeners =
(ArrayList<AnimatorListener>) mListeners.clone();
- for (AnimatorListener listener : tmpListeners) {
- listener.onAnimationEnd(this);
+ int numListeners = tmpListeners.size();
+ for (int i = 0; i < numListeners; ++i) {
+ tmpListeners.get(i).onAnimationEnd(this);
}
}
}
@@ -1077,8 +989,9 @@ public class ValueAnimator extends Animator {
// just for delayed animations
ArrayList<AnimatorListener> tmpListeners =
(ArrayList<AnimatorListener>) mListeners.clone();
- for (AnimatorListener listener : tmpListeners) {
- listener.onAnimationStart(this);
+ int numListeners = tmpListeners.size();
+ for (int i = 0; i < numListeners; ++i) {
+ tmpListeners.get(i).onAnimationStart(this);
}
}
}
@@ -1147,8 +1060,9 @@ public class ValueAnimator extends Animator {
if (mCurrentIteration < mRepeatCount || mRepeatCount == INFINITE) {
// Time to repeat
if (mListeners != null) {
- for (AnimatorListener listener : mListeners) {
- listener.onAnimationRepeat(this);
+ int numListeners = mListeners.size();
+ for (int i = 0; i < numListeners; ++i) {
+ mListeners.get(i).onAnimationRepeat(this);
}
}
++mCurrentIteration;
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index a9f0780..7276044 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -8288,7 +8288,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
(ArrayList<OnLayoutChangeListener>) mOnLayoutChangeListeners.clone();
int numListeners = listenersCopy.size();
for (int i = 0; i < numListeners; ++i) {
- listenersCopy.get(i).onLayoutChange(this, l, r, t, b, oldL, oldT, oldR, oldB);
+ listenersCopy.get(i).onLayoutChange(this, l, t, r, b, oldL, oldT, oldR, oldB);
}
}
}