API Review: split out BidirectionalTypeConverter.
Bug 14997858
Change-Id: I1f2ccf7c4e60320c8df759702a8f2fa24fd3acd2
diff --git a/api/current.txt b/api/current.txt
index 6386ff2..0ce7207 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -2831,6 +2831,12 @@
method public java.lang.Object evaluate(float, java.lang.Object, java.lang.Object);
}
+ public abstract class BidirectionalTypeConverter extends android.animation.TypeConverter {
+ ctor public BidirectionalTypeConverter(java.lang.Class<T>, java.lang.Class<V>);
+ method public abstract T convertBack(V);
+ method public android.animation.BidirectionalTypeConverter<V, T> invert();
+ }
+
public class FloatArrayEvaluator implements android.animation.TypeEvaluator {
ctor public FloatArrayEvaluator();
ctor public FloatArrayEvaluator(float[]);
@@ -3009,7 +3015,6 @@
public abstract class TypeConverter {
ctor public TypeConverter(java.lang.Class<T>, java.lang.Class<V>);
method public abstract V convert(T);
- method public T convertBack(V);
}
public abstract interface TypeEvaluator {
diff --git a/core/java/android/animation/BidirectionalTypeConverter.java b/core/java/android/animation/BidirectionalTypeConverter.java
new file mode 100644
index 0000000..960650e
--- /dev/null
+++ b/core/java/android/animation/BidirectionalTypeConverter.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2014 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;
+
+/**
+ * Abstract base class used convert type T to another type V and back again. This
+ * is necessary when the value types of in animation are different from the property
+ * type. BidirectionalTypeConverter is needed when only the final value for the
+ * animation is supplied to animators.
+ * @see PropertyValuesHolder#setConverter(TypeConverter)
+ */
+public abstract class BidirectionalTypeConverter<T, V> extends TypeConverter<T, V> {
+ private BidirectionalTypeConverter mInvertedConverter;
+
+ public BidirectionalTypeConverter(Class<T> fromClass, Class<V> toClass) {
+ super(fromClass, toClass);
+ }
+
+ /**
+ * Does a conversion from the target type back to the source type. The subclass
+ * must implement this when a TypeConverter is used in animations and current
+ * values will need to be read for an animation.
+ * @param value The Object to convert.
+ * @return A value of type T, converted from <code>value</code>.
+ */
+ public abstract T convertBack(V value);
+
+ /**
+ * Returns the inverse of this converter, where the from and to classes are reversed.
+ * The inverted converter uses this convert to call {@link #convertBack(Object)} for
+ * {@link #convert(Object)} calls and {@link #convert(Object)} for
+ * {@link #convertBack(Object)} calls.
+ * @return The inverse of this converter, where the from and to classes are reversed.
+ */
+ public BidirectionalTypeConverter<V, T> invert() {
+ if (mInvertedConverter == null) {
+ mInvertedConverter = new InvertedConverter(this);
+ }
+ return mInvertedConverter;
+ }
+
+ private static class InvertedConverter<From, To> extends BidirectionalTypeConverter<From, To> {
+ private BidirectionalTypeConverter<To, From> mConverter;
+
+ public InvertedConverter(BidirectionalTypeConverter<To, From> converter) {
+ super(converter.getTargetType(), converter.getSourceType());
+ mConverter = converter;
+ }
+
+ @Override
+ public From convertBack(To value) {
+ return mConverter.convert(value);
+ }
+
+ @Override
+ public To convert(From value) {
+ return mConverter.convertBack(value);
+ }
+ }
+}
diff --git a/core/java/android/animation/ObjectAnimator.java b/core/java/android/animation/ObjectAnimator.java
index c0ce795..130754e 100644
--- a/core/java/android/animation/ObjectAnimator.java
+++ b/core/java/android/animation/ObjectAnimator.java
@@ -610,8 +610,8 @@
* along the way, and an ending value (these values will be distributed evenly across
* the duration of the animation). This variant supplies a <code>TypeConverter</code> to
* convert from the animated values to the type of the property. If only one value is
- * supplied, the <code>TypeConverter</code> must implement
- * {@link TypeConverter#convertBack(Object)} to retrieve the current value.
+ * supplied, the <code>TypeConverter</code> must be a
+ * {@link android.animation.BidirectionalTypeConverter} to retrieve the current value.
*
* @param target The object whose property is to be animated.
* @param property The property being animated.
diff --git a/core/java/android/animation/PropertyValuesHolder.java b/core/java/android/animation/PropertyValuesHolder.java
index 8fce80a..bf2924c 100644
--- a/core/java/android/animation/PropertyValuesHolder.java
+++ b/core/java/android/animation/PropertyValuesHolder.java
@@ -456,7 +456,7 @@
* cannot automatically interpolate between objects of unknown type. This variant also
* takes a <code>TypeConverter</code> to convert from animated values to the type
* of the property. If only one value is supplied, the <code>TypeConverter</code>
- * must implement {@link TypeConverter#convertBack(Object)} to retrieve the current
+ * must be a {@link android.animation.BidirectionalTypeConverter} to retrieve the current
* value.
*
* @param property The property being animated. Should not be null.
@@ -635,6 +635,8 @@
/**
* Sets the converter to convert from the values type to the setter's parameter type.
+ * If only one value is supplied, <var>converter</var> must be a
+ * {@link android.animation.BidirectionalTypeConverter}.
* @param converter The converter to use to convert values.
*/
public void setConverter(TypeConverter converter) {
@@ -816,12 +818,12 @@
private Object convertBack(Object value) {
if (mConverter != null) {
- value = mConverter.convertBack(value);
- if (value == null) {
+ if (!(mConverter instanceof BidirectionalTypeConverter)) {
throw new IllegalArgumentException("Converter "
+ mConverter.getClass().getName()
- + " must implement convertBack and not return null.");
+ + " must be a BidirectionalTypeConverter");
}
+ value = ((BidirectionalTypeConverter) mConverter).convertBack(value);
}
return value;
}
diff --git a/core/java/android/animation/TypeConverter.java b/core/java/android/animation/TypeConverter.java
index 03b3eb5..9ead2ad 100644
--- a/core/java/android/animation/TypeConverter.java
+++ b/core/java/android/animation/TypeConverter.java
@@ -53,16 +53,4 @@
* @return A value of type V, converted from <code>value</code>.
*/
public abstract V convert(T value);
-
- /**
- * Does a conversion from the target type back to the source type. The subclass
- * must implement this when a TypeConverter is used in animations and current
- * values will need to be read for an animation. By default, this will return null,
- * indicating that back-conversion is not supported.
- * @param value The Object to convert.
- * @return A value of type T, converted from <code>value</code>.
- */
- public T convertBack(V value) {
- return null;
- }
}