Implement NativeAnimated offsets on Android
Summary: This diff implements NativeAnimation offsets on Android. Running the examples should show no change; however, calling `setOffset()` should offset the final value for any value node by that amount. This brings Android up to date with JS and iOS animation APIs. Closes https://github.com/facebook/react-native/pull/10680 Differential Revision: D4119609 fbshipit-source-id: 96dccdf25f67c64c6787fd9ac762ec841cefc46a
This commit is contained in:
parent
68c61203ac
commit
8e81644f64
|
@ -39,7 +39,7 @@ import com.facebook.react.bridge.ReadableMap;
|
|||
for (int i = 0; i < mInputNodes.length; i++) {
|
||||
AnimatedNode animatedNode = mNativeAnimatedNodesManager.getNodeById(mInputNodes[i]);
|
||||
if (animatedNode != null && animatedNode instanceof ValueAnimatedNode) {
|
||||
mValue += ((ValueAnimatedNode) animatedNode).mValue;
|
||||
mValue += ((ValueAnimatedNode) animatedNode).getValue();
|
||||
} else {
|
||||
throw new JSApplicationCausedNativeException("Illegal node ID set as an input for " +
|
||||
"Animated.Add node");
|
||||
|
|
|
@ -48,6 +48,6 @@ import com.facebook.react.bridge.ReadableMap;
|
|||
|
||||
}
|
||||
|
||||
return ((ValueAnimatedNode) animatedNode).mValue;
|
||||
return ((ValueAnimatedNode) animatedNode).getValue();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ import com.facebook.react.bridge.ReadableMap;
|
|||
for (int i = 0; i < mInputNodes.length; i++) {
|
||||
AnimatedNode animatedNode = mNativeAnimatedNodesManager.getNodeById(mInputNodes[i]);
|
||||
if (animatedNode != null && animatedNode instanceof ValueAnimatedNode) {
|
||||
double value = ((ValueAnimatedNode) animatedNode).mValue;
|
||||
double value = ((ValueAnimatedNode) animatedNode).getValue();
|
||||
if (i == 0) {
|
||||
mValue = value;
|
||||
continue;
|
||||
|
|
|
@ -136,6 +136,6 @@ import javax.annotation.Nullable;
|
|||
throw new IllegalStateException("Trying to update interpolation node that has not been " +
|
||||
"attached to the parent");
|
||||
}
|
||||
mValue = interpolate(mParent.mValue, mInputRange, mOutputRange, mExtrapolateLeft, mExtrapolateRight);
|
||||
mValue = interpolate(mParent.getValue(), mInputRange, mOutputRange, mExtrapolateLeft, mExtrapolateRight);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ import com.facebook.react.bridge.ReadableMap;
|
|||
for (int i = 0; i < mInputNodes.length; i++) {
|
||||
AnimatedNode animatedNode = mNativeAnimatedNodesManager.getNodeById(mInputNodes[i]);
|
||||
if (animatedNode != null && animatedNode instanceof ValueAnimatedNode) {
|
||||
mValue *= ((ValueAnimatedNode) animatedNode).mValue;
|
||||
mValue *= ((ValueAnimatedNode) animatedNode).getValue();
|
||||
} else {
|
||||
throw new JSApplicationCausedNativeException("Illegal node ID set as an input for " +
|
||||
"Animated.multiply node");
|
||||
|
|
|
@ -242,6 +242,26 @@ public class NativeAnimatedModule extends ReactContextBaseJavaModule implements
|
|||
});
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void setAnimatedNodeOffset(final int tag, final double value) {
|
||||
mOperations.add(new UIThreadOperation() {
|
||||
@Override
|
||||
public void execute(NativeAnimatedNodesManager animatedNodesManager) {
|
||||
animatedNodesManager.setAnimatedNodeOffset(tag, value);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void flattenAnimatedNodeOffset(final int tag) {
|
||||
mOperations.add(new UIThreadOperation() {
|
||||
@Override
|
||||
public void execute(NativeAnimatedNodesManager animatedNodesManager) {
|
||||
animatedNodesManager.flattenAnimatedNodeOffset(tag);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void startAnimatingNode(
|
||||
final int animationId,
|
||||
|
|
|
@ -136,6 +136,25 @@ import javax.annotation.Nullable;
|
|||
mUpdatedNodes.add(node);
|
||||
}
|
||||
|
||||
public void setAnimatedNodeOffset(int tag, double offset) {
|
||||
AnimatedNode node = mAnimatedNodes.get(tag);
|
||||
if (node == null || !(node instanceof ValueAnimatedNode)) {
|
||||
throw new JSApplicationIllegalArgumentException("Animated node with tag " + tag +
|
||||
" does not exists or is not a 'value' node");
|
||||
}
|
||||
((ValueAnimatedNode) node).mOffset = offset;
|
||||
mUpdatedNodes.add(node);
|
||||
}
|
||||
|
||||
public void flattenAnimatedNodeOffset(int tag) {
|
||||
AnimatedNode node = mAnimatedNodes.get(tag);
|
||||
if (node == null || !(node instanceof ValueAnimatedNode)) {
|
||||
throw new JSApplicationIllegalArgumentException("Animated node with tag " + tag +
|
||||
" does not exists or is not a 'value' node");
|
||||
}
|
||||
((ValueAnimatedNode) node).flattenOffset();
|
||||
}
|
||||
|
||||
public void startAnimatingNode(
|
||||
int animationId,
|
||||
int animatedNodeTag,
|
||||
|
|
|
@ -56,7 +56,7 @@ import javax.annotation.Nullable;
|
|||
} else if (node instanceof StyleAnimatedNode) {
|
||||
((StyleAnimatedNode) node).collectViewUpdates(propsMap);
|
||||
} else if (node instanceof ValueAnimatedNode) {
|
||||
propsMap.putDouble(entry.getKey(), ((ValueAnimatedNode) node).mValue);
|
||||
propsMap.putDouble(entry.getKey(), ((ValueAnimatedNode) node).getValue());
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unsupported type of node used in property node " +
|
||||
node.getClass());
|
||||
|
|
|
@ -46,7 +46,7 @@ import javax.annotation.Nullable;
|
|||
} else if (node instanceof TransformAnimatedNode) {
|
||||
((TransformAnimatedNode) node).collectViewUpdates(propsMap);
|
||||
} else if (node instanceof ValueAnimatedNode) {
|
||||
propsMap.putDouble(entry.getKey(), ((ValueAnimatedNode) node).mValue);
|
||||
propsMap.putDouble(entry.getKey(), ((ValueAnimatedNode) node).getValue());
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unsupported type of node used in property node " +
|
||||
node.getClass());
|
||||
|
|
|
@ -70,7 +70,7 @@ import java.util.List;
|
|||
if (node == null) {
|
||||
throw new IllegalArgumentException("Mapped style node does not exists");
|
||||
} else if (node instanceof ValueAnimatedNode) {
|
||||
value = ((ValueAnimatedNode) node).mValue;
|
||||
value = ((ValueAnimatedNode) node).getValue();
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unsupported type of node used as a transform child " +
|
||||
"node " + node.getClass());
|
||||
|
|
|
@ -19,6 +19,7 @@ import javax.annotation.Nullable;
|
|||
*/
|
||||
/*package*/ class ValueAnimatedNode extends AnimatedNode {
|
||||
/*package*/ double mValue = Double.NaN;
|
||||
/*package*/ double mOffset = 0;
|
||||
private @Nullable AnimatedNodeValueListener mValueListener;
|
||||
|
||||
public ValueAnimatedNode() {
|
||||
|
@ -27,6 +28,16 @@ import javax.annotation.Nullable;
|
|||
|
||||
public ValueAnimatedNode(ReadableMap config) {
|
||||
mValue = config.getDouble("value");
|
||||
mOffset = config.getDouble("offset");
|
||||
}
|
||||
|
||||
public double getValue() {
|
||||
return mOffset + mValue;
|
||||
}
|
||||
|
||||
public void flattenOffset() {
|
||||
mValue += mOffset;
|
||||
mOffset = 0;
|
||||
}
|
||||
|
||||
public void onValueUpdate() {
|
||||
|
|
|
@ -121,7 +121,7 @@ public class NativeAnimatedNodeTraversalTest {
|
|||
private void createSimpleAnimatedViewWithOpacity(int viewTag, double opacity) {
|
||||
mNativeAnimatedNodesManager.createAnimatedNode(
|
||||
1,
|
||||
JavaOnlyMap.of("type", "value", "value", opacity));
|
||||
JavaOnlyMap.of("type", "value", "value", opacity, "offset", 0d));
|
||||
mNativeAnimatedNodesManager.createAnimatedNode(
|
||||
2,
|
||||
JavaOnlyMap.of("type", "style", "style", JavaOnlyMap.of("opacity", 1)));
|
||||
|
@ -387,10 +387,10 @@ public class NativeAnimatedNodeTraversalTest {
|
|||
double secondValue) {
|
||||
mNativeAnimatedNodesManager.createAnimatedNode(
|
||||
1,
|
||||
JavaOnlyMap.of("type", "value", "value", 100d));
|
||||
JavaOnlyMap.of("type", "value", "value", 100d, "offset", 0d));
|
||||
mNativeAnimatedNodesManager.createAnimatedNode(
|
||||
2,
|
||||
JavaOnlyMap.of("type", "value", "value", 1000d));
|
||||
JavaOnlyMap.of("type", "value", "value", 1000d, "offset", 0d));
|
||||
|
||||
mNativeAnimatedNodesManager.createAnimatedNode(
|
||||
3,
|
||||
|
@ -558,10 +558,10 @@ public class NativeAnimatedNodeTraversalTest {
|
|||
public void testMultiplicationNode() {
|
||||
mNativeAnimatedNodesManager.createAnimatedNode(
|
||||
1,
|
||||
JavaOnlyMap.of("type", "value", "value", 1d));
|
||||
JavaOnlyMap.of("type", "value", "value", 1d, "offset", 0d));
|
||||
mNativeAnimatedNodesManager.createAnimatedNode(
|
||||
2,
|
||||
JavaOnlyMap.of("type", "value", "value", 5d));
|
||||
JavaOnlyMap.of("type", "value", "value", 5d, "offset", 0d));
|
||||
|
||||
mNativeAnimatedNodesManager.createAnimatedNode(
|
||||
3,
|
||||
|
@ -669,7 +669,7 @@ public class NativeAnimatedNodeTraversalTest {
|
|||
public void testInterpolationNode() {
|
||||
mNativeAnimatedNodesManager.createAnimatedNode(
|
||||
1,
|
||||
JavaOnlyMap.of("type", "value", "value", 10d));
|
||||
JavaOnlyMap.of("type", "value", "value", 10d, "offset", 0d));
|
||||
|
||||
mNativeAnimatedNodesManager.createAnimatedNode(
|
||||
2,
|
||||
|
|
Loading…
Reference in New Issue