diff --git a/Examples/UIExplorer/ListViewPagingExample.js b/Examples/UIExplorer/ListViewPagingExample.js index 7d0ac98f2..b82f272c9 100644 --- a/Examples/UIExplorer/ListViewPagingExample.js +++ b/Examples/UIExplorer/ListViewPagingExample.js @@ -11,7 +11,6 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * @provides ListViewPagingExample * @flow */ 'use strict'; @@ -27,11 +26,6 @@ var { View, } = React; -var NativeModules = require('NativeModules'); -var { - UIManager, -} = NativeModules; - var PAGE_SIZE = 4; var THUMB_URLS = [ 'Thumbnails/like.png', @@ -54,10 +48,6 @@ var Thumb = React.createClass({ getInitialState: function() { return {thumbIndex: this._getThumbIdx(), dir: 'row'}; }, - componentWillMount: function() { - UIManager.setLayoutAnimationEnabledExperimental && - UIManager.setLayoutAnimationEnabledExperimental(true); - }, _getThumbIdx: function() { return Math.floor(Math.random() * THUMB_URLS.length); }, diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyManager.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyManager.java index 744279880..fddd70478 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyManager.java @@ -29,11 +29,9 @@ import com.facebook.react.bridge.Callback; import com.facebook.react.bridge.JSApplicationIllegalArgumentException; import com.facebook.react.bridge.ReactContext; import com.facebook.react.bridge.ReadableArray; -import com.facebook.react.bridge.ReadableMap; import com.facebook.react.bridge.SoftAssertions; import com.facebook.react.bridge.UiThreadUtil; import com.facebook.react.touch.JSResponderHandler; -import com.facebook.react.uimanager.layoutanimation.LayoutAnimationController; /** * Delegate of {@link UIManagerModule} that owns the native view hierarchy and mapping between @@ -68,9 +66,6 @@ import com.facebook.react.uimanager.layoutanimation.LayoutAnimationController; private final ViewManagerRegistry mViewManagers; private final JSResponderHandler mJSResponderHandler = new JSResponderHandler(); private final RootViewManager mRootViewManager = new RootViewManager(); - private final LayoutAnimationController mLayoutAnimator = new LayoutAnimationController(); - - private boolean mLayoutAnimationEnabled; public NativeViewHierarchyManager(ViewManagerRegistry viewManagers) { mAnimationRegistry = new AnimationRegistry(); @@ -85,10 +80,6 @@ import com.facebook.react.uimanager.layoutanimation.LayoutAnimationController; return mAnimationRegistry; } - public void setLayoutAnimationEnabled(boolean enabled) { - mLayoutAnimationEnabled = enabled; - } - public void updateProperties(int tag, CatalystStylesDiffMap props) { UiThreadUtil.assertOnUiThread(); @@ -163,17 +154,8 @@ import com.facebook.react.uimanager.layoutanimation.LayoutAnimationController; } if (parentViewGroupManager != null && !parentViewGroupManager.needsCustomLayoutForChildren()) { - updateLayout(viewToUpdate, x, y, width, height); + viewToUpdate.layout(x, y, x + width, y + height); } - } else { - updateLayout(viewToUpdate, x, y, width, height); - } - } - - private void updateLayout(View viewToUpdate, int x, int y, int width, int height) { - if (mLayoutAnimationEnabled && - mLayoutAnimator.shouldAnimateLayout(viewToUpdate)) { - mLayoutAnimator.applyLayoutUpdate(viewToUpdate, x, y, width, height); } else { viewToUpdate.layout(x, y, x + width, y + height); } @@ -488,14 +470,6 @@ import com.facebook.react.uimanager.layoutanimation.LayoutAnimationController; mJSResponderHandler.clearJSResponder(); } - void configureLayoutAnimation(final ReadableMap config) { - mLayoutAnimator.initializeFromConfig(config); - } - - void clearLayoutAnimation() { - mLayoutAnimator.reset(); - } - /* package */ void startAnimationForNativeView( int reactTag, Animation animation, diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModule.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModule.java index adfd7f3ff..59fd688e3 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModule.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModule.java @@ -383,45 +383,12 @@ public class UIManagerModule extends ReactContextBaseJavaModule implements mUIImplementation.showPopupMenu(reactTag, items, error, success); } - @ReactMethod - public void setMainScrollViewTag(int reactTag) { - // TODO(6588266): Implement if required - } - - /** - * LayoutAnimation API on Android is currently experimental. Therefore, it needs to be enabled - * explicitly in order to avoid regression in existing application written for iOS using this API. - * - * Warning : This method will be removed in future version of React Native, and layout animation - * will be enabled by default, so always check for its existence before invoking it. - * - * TODO(9139831) : remove this method once layout animation is fully stable. - * - * @param enabled whether layout animation is enabled or not - */ - @ReactMethod - public void setLayoutAnimationEnabledExperimental(boolean enabled) { - mOperationsQueue.enqueueSetLayoutAnimationEnabled(enabled); - } - - /** - * Configure an animation to be used for the native layout changes, and native views - * creation. The animation will only apply during the current batch operations. - * - * TODO(7728153) : animating view deletion is currently not supported. - * TODO(7613721) : callbacks are not supported, this feature will likely be killed. - * - * @param config the configuration of the animation for view addition/removal/update. - * @param success will be called when the animation completes, or when the animation get - * interrupted. In this case, callback parameter will be false. - * @param error will be called if there was an error processing the animation - */ @ReactMethod public void configureNextLayoutAnimation( ReadableMap config, - Callback success, - Callback error) { - mOperationsQueue.enqueueConfigureLayoutAnimation(config, success, error); + Callback successCallback, + Callback errorCallback) { + // TODO(6588266): Implement if required } /** diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIViewOperationQueue.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIViewOperationQueue.java index a8dc4aefd..ed507fd3e 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIViewOperationQueue.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIViewOperationQueue.java @@ -23,7 +23,6 @@ import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.SoftAssertions; import com.facebook.react.bridge.ReactContext; import com.facebook.react.bridge.ReadableArray; -import com.facebook.react.bridge.ReadableMap; import com.facebook.react.bridge.UiThreadUtil; import com.facebook.react.uimanager.debug.NotThreadSafeViewHierarchyUpdateDebugListener; import com.facebook.systrace.Systrace; @@ -323,32 +322,6 @@ public class UIViewOperationQueue { } } - private class SetLayoutAnimationEnabledOperation implements UIOperation { - private final boolean mEnabled; - - private SetLayoutAnimationEnabledOperation(final boolean enabled) { - mEnabled = enabled; - } - - @Override - public void execute() { - mNativeViewHierarchyManager.setLayoutAnimationEnabled(mEnabled); - } - } - - private class ConfigureLayoutAnimationOperation implements UIOperation { - private final ReadableMap mConfig; - - private ConfigureLayoutAnimationOperation(final ReadableMap config) { - mConfig = config; - } - - @Override - public void execute() { - mNativeViewHierarchyManager.configureLayoutAnimation(mConfig); - } - } - private final class MeasureOperation implements UIOperation { private final int mReactTag; @@ -603,18 +576,6 @@ public class UIViewOperationQueue { mOperations.add(new RemoveAnimationOperation(animationID)); } - public void enqueueSetLayoutAnimationEnabled( - final boolean enabled) { - mOperations.add(new SetLayoutAnimationEnabledOperation(enabled)); - } - - public void enqueueConfigureLayoutAnimation( - final ReadableMap config, - final Callback onSuccess, - final Callback onError) { - mOperations.add(new ConfigureLayoutAnimationOperation(config)); - } - public void enqueueMeasure( final int reactTag, final Callback callback) { @@ -711,9 +672,6 @@ public class UIViewOperationQueue { mDispatchUIRunnables.get(i).run(); } mDispatchUIRunnables.clear(); - - // Clear layout animation, as animation only apply to current UI operations batch. - mNativeViewHierarchyManager.clearLayoutAnimation(); } ReactChoreographer.getInstance().postFrameCallback( diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/layoutanimation/AbstractLayoutAnimation.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/layoutanimation/AbstractLayoutAnimation.java deleted file mode 100644 index c29d7ae0b..000000000 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/layoutanimation/AbstractLayoutAnimation.java +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright 2004-present Facebook. All Rights Reserved. - -package com.facebook.react.uimanager.layoutanimation; - -import javax.annotation.Nullable; - -import java.util.Map; - -import android.view.View; -import android.view.animation.AccelerateDecelerateInterpolator; -import android.view.animation.AccelerateInterpolator; -import android.view.animation.Animation; -import android.view.animation.DecelerateInterpolator; -import android.view.animation.Interpolator; -import android.view.animation.LinearInterpolator; - -import com.facebook.react.bridge.ReadableMap; -import com.facebook.react.common.MapBuilder; -import com.facebook.react.uimanager.IllegalViewOperationException; - -/** - * Class responsible for parsing and converting layout animation data into native {@link Animation} - * in order to animate layout when a valid configuration has been supplied by the application. - */ -/* package */ abstract class AbstractLayoutAnimation { - - // Forces animation to be playing 10x slower, used for debug purposes. - private static final boolean SLOWDOWN_ANIMATION_MODE = false; - - abstract boolean isValid(); - - /** - * Create an animation object for the current animation type, based on the view and final screen - * coordinates. If the application-supplied configuraiton does not specify an animation definition - * for this types, or if the animation definition is invalid, returns null. - */ - abstract @Nullable Animation createAnimationImpl(View view, int x, int y, int width, int height); - - private static final Map INTERPOLATOR = MapBuilder.of( - InterpolatorType.LINEAR, new LinearInterpolator(), - InterpolatorType.EASE_IN, new AccelerateInterpolator(), - InterpolatorType.EASE_OUT, new DecelerateInterpolator(), - InterpolatorType.EASE_IN_EASE_OUT, new AccelerateDecelerateInterpolator(), - InterpolatorType.SPRING, new SimpleSpringInterpolator()); - - private @Nullable Interpolator mInterpolator; - private int mDelayMs; - - protected @Nullable AnimatedPropertyType mAnimatedProperty; - protected int mDurationMs; - - public void reset() { - mAnimatedProperty = null; - mDurationMs = 0; - mDelayMs = 0; - mInterpolator = null; - } - - public void initializeFromConfig(ReadableMap data, int globalDuration) { - mAnimatedProperty = data.hasKey("property") ? - AnimatedPropertyType.fromString(data.getString("property")) : null; - mDurationMs = data.hasKey("duration") ? data.getInt("duration") : globalDuration; - mDelayMs = data.hasKey("delay") ? data.getInt("delay") : 0; - mInterpolator = data.hasKey("type") ? - getInterpolator(InterpolatorType.fromString(data.getString("type"))) : null; - - if (!isValid()) { - throw new IllegalViewOperationException("Invalid layout animation : " + data); - } - } - - /** - * Create an animation object to be used to animate the view, based on the animation config - * supplied at initialization time and the new view position and size. - * - * @param view the view to create the animation for - * @param x the new X position for the view - * @param y the new Y position for the view - * @param width the new width value for the view - * @param height the new height value for the view - */ - public final @Nullable Animation createAnimation( - View view, - int x, - int y, - int width, - int height) { - if (!isValid()) { - return null; - } - Animation animation = createAnimationImpl(view, x, y, width, height); - if (animation != null) { - int slowdownFactor = SLOWDOWN_ANIMATION_MODE ? 10 : 1; - animation.setDuration(mDurationMs * slowdownFactor); - animation.setStartOffset(mDelayMs * slowdownFactor); - animation.setInterpolator(mInterpolator); - } - return animation; - } - - private static Interpolator getInterpolator(InterpolatorType type) { - Interpolator interpolator = INTERPOLATOR.get(type); - if (interpolator == null) { - throw new IllegalArgumentException("Missing interpolator for type : " + type); - } - return interpolator; - } -} diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/layoutanimation/AnimatedPropertyType.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/layoutanimation/AnimatedPropertyType.java deleted file mode 100644 index 51a9d246c..000000000 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/layoutanimation/AnimatedPropertyType.java +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2004-present Facebook. All Rights Reserved. - -package com.facebook.react.uimanager.layoutanimation; - -/** - * Enum representing the different view properties that can be used when animating layout for - * view creation. - */ -/* package */ enum AnimatedPropertyType { - OPACITY("opacity"), - SCALE_XY("scaleXY"); - - private final String mName; - - private AnimatedPropertyType(String name) { - mName = name; - } - - public static AnimatedPropertyType fromString(String name) { - for (AnimatedPropertyType property : AnimatedPropertyType.values()) { - if (property.toString().equalsIgnoreCase(name)) { - return property; - } - } - throw new IllegalArgumentException("Unsupported animated property : " + name); - } - - @Override - public String toString() { - return mName; - } -} diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/layoutanimation/BaseLayoutAnimation.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/layoutanimation/BaseLayoutAnimation.java deleted file mode 100644 index 9d3d0f45a..000000000 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/layoutanimation/BaseLayoutAnimation.java +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2004-present Facebook. All Rights Reserved. - -package com.facebook.react.uimanager.layoutanimation; - -import android.view.View; -import android.view.animation.Animation; -import android.view.animation.ScaleAnimation; - -import com.facebook.react.uimanager.IllegalViewOperationException; - -/** - * Class responsible for default layout animation, i.e animation of view creation and deletion. - */ -/* package */ abstract class BaseLayoutAnimation extends AbstractLayoutAnimation { - - abstract boolean isReverse(); - - @Override - boolean isValid() { - return mDurationMs > 0 && mAnimatedProperty != null; - } - - @Override - Animation createAnimationImpl(View view, int x, int y, int width, int height) { - float fromValue = isReverse() ? 1.0f : 0.0f; - float toValue = isReverse() ? 0.0f : 1.0f; - if (mAnimatedProperty != null) { - switch (mAnimatedProperty) { - case OPACITY: - return new OpacityAnimation(view, fromValue, toValue); - case SCALE_XY: - return new ScaleAnimation( - fromValue, - toValue, - fromValue, - toValue, - Animation.RELATIVE_TO_PARENT, - .5f, - Animation.RELATIVE_TO_PARENT, - .5f); - default: - throw new IllegalViewOperationException( - "Missing animation for property : " + mAnimatedProperty); - } - } - throw new IllegalViewOperationException("Missing animated property from animation config"); - } -} diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/layoutanimation/HandlesLayout.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/layoutanimation/HandlesLayout.java deleted file mode 100644 index 9f3c907e9..000000000 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/layoutanimation/HandlesLayout.java +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright 2004-present Facebook. All Rights Reserved. - -package com.facebook.react.uimanager.layoutanimation; - -/** - * Marker interface to indicate a given animation type takes care of updating the view layout. - */ -/* package */ interface HandleLayout { - -} diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/layoutanimation/InterpolatorType.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/layoutanimation/InterpolatorType.java deleted file mode 100644 index f59675a8f..000000000 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/layoutanimation/InterpolatorType.java +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2004-present Facebook. All Rights Reserved. - -package com.facebook.react.uimanager.layoutanimation; - -/** - * Enum representing the different interpolators that can be used in layout animation configuration. - */ -/* package */ enum InterpolatorType { - LINEAR("linear"), - EASE_IN("easeIn"), - EASE_OUT("easeOut"), - EASE_IN_EASE_OUT("easeInEaseOut"), - SPRING("spring"); - - private final String mName; - - private InterpolatorType(String name) { - mName = name; - } - - public static InterpolatorType fromString(String name) { - for (InterpolatorType type : InterpolatorType.values()) { - if (type.toString().equalsIgnoreCase(name)) { - return type; - } - } - throw new IllegalArgumentException("Unsupported interpolation type : " + name); - } - - @Override - public String toString() { - return mName; - } -} diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/layoutanimation/LayoutAnimationController.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/layoutanimation/LayoutAnimationController.java deleted file mode 100644 index d3522947f..000000000 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/layoutanimation/LayoutAnimationController.java +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright 2004-present Facebook. All Rights Reserved. - -package com.facebook.react.uimanager.layoutanimation; - -import javax.annotation.Nullable; -import javax.annotation.concurrent.NotThreadSafe; - -import android.view.View; -import android.view.animation.Animation; - -import com.facebook.react.bridge.ReadableMap; -import com.facebook.react.bridge.UiThreadUtil; - -/** - * Class responsible for animation layout changes, if a valid layout animation config has been - * supplied. If not animation is available, layout change is applied immediately instead of - * performing an animation. - * - * TODO(7613721): Invoke success callback at the end of animation and when animation gets cancelled. - */ -@NotThreadSafe -public class LayoutAnimationController { - - private static final boolean ENABLED = true; - - private final AbstractLayoutAnimation mLayoutCreateAnimation = new LayoutCreateAnimation(); - private final AbstractLayoutAnimation mLayoutUpdateAnimation = new LayoutUpdateAnimation(); - private boolean mShouldAnimateLayout; - - public void initializeFromConfig(final @Nullable ReadableMap config) { - if (!ENABLED) { - return; - } - - if (config == null) { - reset(); - return; - } - - mShouldAnimateLayout = false; - int globalDuration = config.hasKey("duration") ? config.getInt("duration") : 0; - if (config.hasKey(LayoutAnimationType.CREATE.toString())) { - mLayoutCreateAnimation.initializeFromConfig( - config.getMap(LayoutAnimationType.CREATE.toString()), globalDuration); - mShouldAnimateLayout = true; - } - if (config.hasKey(LayoutAnimationType.UPDATE.toString())) { - mLayoutUpdateAnimation.initializeFromConfig( - config.getMap(LayoutAnimationType.UPDATE.toString()), globalDuration); - mShouldAnimateLayout = true; - } - } - - public void reset() { - mLayoutCreateAnimation.reset(); - mLayoutUpdateAnimation.reset(); - mShouldAnimateLayout = false; - } - - public boolean shouldAnimateLayout(View viewToAnimate) { - // if view parent is null, skip animation: view have been clipped, we don't want animation to - // resume when view is re-attached to parent, which is the standard android animation behavior. - return mShouldAnimateLayout && viewToAnimate.getParent() != null; - } - - /** - * Update layout of given view, via immediate update or animation depending on the current batch - * layout animation configuration supplied during initialization. - * - * @param view the view to update layout of - * @param x the new X position for the view - * @param y the new Y position for the view - * @param width the new width value for the view - * @param height the new height value for the view - */ - public void applyLayoutUpdate(View view, int x, int y, int width, int height) { - UiThreadUtil.assertOnUiThread(); - - // Determine which animation to use : if view is initially invisible, use create animation. - // If view is becoming invisible, use delete animation. Otherwise, use update animation. - // This approach is easier than maintaining a list of tags for recently created/deleted views. - AbstractLayoutAnimation layoutAnimation = (view.getWidth() == 0 || view.getHeight() == 0) ? - mLayoutCreateAnimation : - mLayoutUpdateAnimation; - - Animation animation = layoutAnimation.createAnimation(view, x, y, width, height); - if (animation == null || !(animation instanceof HandleLayout)) { - view.layout(x, y, x + width, y + height); - } - if (animation != null) { - view.startAnimation(animation); - } - } -} diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/layoutanimation/LayoutAnimationType.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/layoutanimation/LayoutAnimationType.java deleted file mode 100644 index 0f3d9d7fd..000000000 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/layoutanimation/LayoutAnimationType.java +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2004-present Facebook. All Rights Reserved. - -package com.facebook.react.uimanager.layoutanimation; - -/** - * Enum representing the different animation type that can be specified in layout animation config. - */ -/* package */ enum LayoutAnimationType { - CREATE("create"), - UPDATE("update"); - - private final String mName; - - private LayoutAnimationType(String name) { - mName = name; - } - - @Override - public String toString() { - return mName; - } -} diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/layoutanimation/LayoutCreateAnimation.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/layoutanimation/LayoutCreateAnimation.java deleted file mode 100644 index a989e625c..000000000 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/layoutanimation/LayoutCreateAnimation.java +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2004-present Facebook. All Rights Reserved. - -package com.facebook.react.uimanager.layoutanimation; - -/** - * Class responsible for handling layout view creation animation, applied to view whenever a - * valid config was supplied for the layout animation of CREATE type. - */ -/* package */ class LayoutCreateAnimation extends BaseLayoutAnimation { - - @Override - boolean isReverse() { - return false; - } -} diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/layoutanimation/LayoutUpdateAnimation.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/layoutanimation/LayoutUpdateAnimation.java deleted file mode 100644 index 8189716f7..000000000 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/layoutanimation/LayoutUpdateAnimation.java +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright 2004-present Facebook. All Rights Reserved. - -package com.facebook.react.uimanager.layoutanimation; - -import javax.annotation.Nullable; - -import android.view.View; -import android.view.animation.Animation; -import android.view.animation.TranslateAnimation; - -/** - * Class responsible for handling layout update animation, applied to view whenever a valid config - * was supplied for the layout animation of UPDATE type. - */ -/* package */ class LayoutUpdateAnimation extends AbstractLayoutAnimation { - - // We are currently not enabling translation GPU-accelerated animated, as it creates odd - // artifacts with native react scrollview. This needs to be investigated. - private static final boolean USE_TRANSLATE_ANIMATION = false; - - @Override - boolean isValid() { - return mDurationMs > 0; - } - - @Override - @Nullable Animation createAnimationImpl(View view, int x, int y, int width, int height) { - boolean animateLocation = view.getX() != x || view.getY() != y; - boolean animateSize = view.getWidth() != width || view.getHeight() != height; - if (!animateLocation && !animateSize) { - return null; - } else if (animateLocation && !animateSize && USE_TRANSLATE_ANIMATION) { - // Use GPU-accelerated animation, however we loose the ability to resume interrupted - // animation where it was left off. We may be able to listen to animation interruption - // and set the layout manually in this case, so that next animation kicks off smoothly. - return new TranslateAnimation(view.getX() - x, 0, view.getY() - y, 0); - } else { - // Animation is sub-optimal for perf, but scale transformation can't be use in this case. - return new PositionAndSizeAnimation(view, x, y, width, height); - } - } -} diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/layoutanimation/OpacityAnimation.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/layoutanimation/OpacityAnimation.java deleted file mode 100644 index a7ad69002..000000000 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/layoutanimation/OpacityAnimation.java +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright 2004-present Facebook. All Rights Reserved. - -package com.facebook.react.uimanager.layoutanimation; - -import android.view.View; -import android.view.animation.Animation; -import android.view.animation.Transformation; - -/** - * Animation responsible for updating opacity of a view. It should ideally use hardware texture - * to optimize rendering performances. - */ -/* package */ class OpacityAnimation extends Animation { - - static class OpacityAnimationListener implements AnimationListener { - - private final View mView; - private boolean mLayerTypeChanged = false; - - public OpacityAnimationListener(View view) { - mView = view; - } - - @Override - public void onAnimationStart(Animation animation) { - if (mView.hasOverlappingRendering() && - mView.getLayerType() == View.LAYER_TYPE_NONE) { - mLayerTypeChanged = true; - mView.setLayerType(View.LAYER_TYPE_HARDWARE, null); - } - } - - @Override - public void onAnimationEnd(Animation animation) { - if (mLayerTypeChanged) { - mView.setLayerType(View.LAYER_TYPE_NONE, null); - } - } - - @Override - public void onAnimationRepeat(Animation animation) { - // do nothing - } - } - - private final View mView; - private final float mStartOpacity, mDeltaOpacity; - - public OpacityAnimation(View view, float startOpacity, float endOpacity) { - mView = view; - mStartOpacity = startOpacity; - mDeltaOpacity = endOpacity - startOpacity; - - setAnimationListener(new OpacityAnimationListener(view)); - } - - @Override - protected void applyTransformation(float interpolatedTime, Transformation t) { - mView.setAlpha(mStartOpacity + mDeltaOpacity * interpolatedTime); - } - - @Override - public boolean willChangeBounds() { - return false; - } -} diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/layoutanimation/PositionAndSizeAnimation.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/layoutanimation/PositionAndSizeAnimation.java deleted file mode 100644 index 2adf81a6b..000000000 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/layoutanimation/PositionAndSizeAnimation.java +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright 2004-present Facebook. All Rights Reserved. - -package com.facebook.react.uimanager.layoutanimation; - -import android.view.View; -import android.view.animation.Animation; -import android.view.animation.Transformation; - -/** - * Animation responsible for updating size and position of a view. We can't use scaling as view - * content may not necessarily stretch. As a result, this approach is inefficient because of - * layout passes occurring on every frame. - * What we might want to try to do instead is use a combined ScaleAnimation and TranslateAnimation. - */ -/* package */ class PositionAndSizeAnimation extends Animation implements HandleLayout { - - private final View mView; - private final float mStartX, mStartY, mDeltaX, mDeltaY; - private final int mStartWidth, mStartHeight, mDeltaWidth, mDeltaHeight; - - public PositionAndSizeAnimation(View view, int x, int y, int width, int height) { - mView = view; - - mStartX = view.getX(); - mStartY = view.getY(); - mStartWidth = view.getWidth(); - mStartHeight = view.getHeight(); - - mDeltaX = x - mStartX; - mDeltaY = y - mStartY; - mDeltaWidth = width - mStartWidth; - mDeltaHeight = height - mStartHeight; - } - - @Override - protected void applyTransformation(float interpolatedTime, Transformation t) { - float newX = mStartX + mDeltaX * interpolatedTime; - float newY = mStartY + mDeltaY * interpolatedTime; - float newWidth = mStartWidth + mDeltaWidth * interpolatedTime; - float newHeight = mStartHeight + mDeltaHeight * interpolatedTime; - mView.layout( - Math.round(newX), - Math.round(newY), - Math.round(newX + newWidth), - Math.round(newY + newHeight)); - } - - @Override - public boolean willChangeBounds() { - return true; - } -} diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/layoutanimation/SimpleSpringInterpolator.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/layoutanimation/SimpleSpringInterpolator.java deleted file mode 100644 index 9696fe90a..000000000 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/layoutanimation/SimpleSpringInterpolator.java +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2004-present Facebook. All Rights Reserved. - -package com.facebook.react.uimanager.layoutanimation; - -import android.view.animation.Interpolator; - -/** - * Simple spring interpolator - */ -//TODO(7613736): Improve spring interpolator with friction and damping variable support -/* package */ class SimpleSpringInterpolator implements Interpolator { - - private static final float FACTOR = 0.5f; - - @Override - public float getInterpolation(float input) { - return (float) - (1 + Math.pow(2, -10 * input) * Math.sin((input - FACTOR / 4) * Math.PI * 2 / FACTOR)); - } -} diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.java b/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.java index 9e2728db4..134b6492b 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.java @@ -16,7 +16,6 @@ import android.graphics.Color; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.graphics.drawable.LayerDrawable; -import android.view.animation.Animation; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; @@ -287,15 +286,7 @@ public class ReactViewGroup extends ViewGroup implements boolean intersects = clippingRect .intersects(sHelperRect.left, sHelperRect.top, sHelperRect.right, sHelperRect.bottom); boolean needUpdateClippingRecursive = false; - // We never want to clip children that are being animated, as this can easily break layout : - // when layout animation changes size and/or position of views contained inside a listview that - // clips offscreen children, we need to ensure that, when view exits the viewport, final size - // and position is set prior to removing the view from its listview parent. - // Otherwise, when view gets re-attached again, i.e when it re-enters the viewport after scroll, - // it won't be size and located properly. - Animation animation = child.getAnimation(); - boolean isAnimating = animation != null && !animation.hasEnded(); - if (!intersects && child.getParent() != null && !isAnimating) { + if (!intersects && child.getParent() != null) { // We can try saving on invalidate call here as the view that we remove is out of visible area // therefore invalidation is not necessary. super.removeViewsInLayout(idx - clippedSoFar, 1);