Skip to content

Commit d9a8222

Browse files
javachefacebook-github-bot
authored andcommitted
Back out "[react-native] Remove experimental gating for LayoutAnimation on Android"
Summary: We've identified a couple of remaining issues that need to be re-tested before we can ship this more broadly. Reviewed By: fred2028 Differential Revision: D14775730 fbshipit-source-id: 22402149066c5fbe72c36fcf7f547d63feaf5241
1 parent 691f2f9 commit d9a8222

File tree

7 files changed

+67
-12
lines changed

7 files changed

+67
-12
lines changed

Diff for: Libraries/LayoutAnimation/LayoutAnimation.js

+4
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,10 @@ const Presets = {
9090
* next layout happens.
9191
*
9292
* A common way to use this API is to call it before calling `setState`.
93+
*
94+
* Note that in order to get this to work on **Android** you need to set the following flags via `UIManager`:
95+
*
96+
* UIManager.setLayoutAnimationEnabledExperimental && UIManager.setLayoutAnimationEnabledExperimental(true);
9397
*/
9498
const LayoutAnimation = {
9599
/**

Diff for: Libraries/ReactNative/UIManager.js

-9
Original file line numberDiff line numberDiff line change
@@ -100,15 +100,6 @@ function lazifyViewManagerConfig(viewName) {
100100
}
101101
}
102102

103-
if (Platform.OS === 'android') {
104-
UIManager.setLayoutAnimationEnabledExperimental = () => {
105-
console.warn(
106-
'setLayoutAnimationEnabledExperimental is deprecated. ' +
107-
'Layout animations are enabled by default',
108-
);
109-
};
110-
}
111-
112103
/**
113104
* Copies the ViewManager constants and commands into UIManager. This is
114105
* only needed for iOS, which puts the constants in the ViewManager

Diff for: RNTester/js/RNTesterApp.android.js

+3
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,16 @@ const RNTesterExampleList = require('./RNTesterExampleList');
2727
* making Flow check .android.js files. */
2828
const RNTesterList = require('./RNTesterList');
2929
const RNTesterNavigationReducer = require('./RNTesterNavigationReducer');
30+
const UIManager = require('UIManager');
3031
const URIActionMap = require('./URIActionMap');
3132
const View = require('View');
3233

3334
const nativeImageSource = require('nativeImageSource');
3435

3536
import type {RNTesterNavigationState} from './RNTesterNavigationReducer';
3637

38+
UIManager.setLayoutAnimationEnabledExperimental(true);
39+
3740
const DRAWER_WIDTH_LEFT = 56;
3841

3942
type Props = {

Diff for: ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyManager.java

+11-3
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ public class NativeViewHierarchyManager {
7474
private final LayoutAnimationController mLayoutAnimator = new LayoutAnimationController();
7575
private final Map<Integer, SparseIntArray> mTagsToPendingIndicesToDelete = new HashMap<>();
7676

77+
private boolean mLayoutAnimationEnabled;
7778
private PopupMenu mPopupMenu;
7879

7980
public NativeViewHierarchyManager(ViewManagerRegistry viewManagers) {
@@ -105,6 +106,10 @@ public synchronized final ViewManager resolveViewManager(int tag) {
105106
return viewManager;
106107
}
107108

109+
public void setLayoutAnimationEnabled(boolean enabled) {
110+
mLayoutAnimationEnabled = enabled;
111+
}
112+
108113
public synchronized void updateInstanceHandle(int tag, long instanceHandle) {
109114
UiThreadUtil.assertOnUiThread();
110115

@@ -220,7 +225,8 @@ public long getInstanceHandle(int reactTag) {
220225
}
221226

222227
private void updateLayout(View viewToUpdate, int x, int y, int width, int height) {
223-
if (mLayoutAnimator.shouldAnimateLayout(viewToUpdate)) {
228+
if (mLayoutAnimationEnabled &&
229+
mLayoutAnimator.shouldAnimateLayout(viewToUpdate)) {
224230
mLayoutAnimator.applyLayoutUpdate(viewToUpdate, x, y, width, height);
225231
} else {
226232
viewToUpdate.layout(x, y, x + width, y + height);
@@ -427,7 +433,8 @@ public synchronized void manageChildren(
427433
int normalizedIndexToRemove = normalizeIndex(indexToRemove, pendingIndicesToDelete);
428434
View viewToRemove = viewManager.getChildAt(viewToManage, normalizedIndexToRemove);
429435

430-
if (mLayoutAnimator.shouldAnimateLayout(viewToRemove) &&
436+
if (mLayoutAnimationEnabled &&
437+
mLayoutAnimator.shouldAnimateLayout(viewToRemove) &&
431438
arrayContains(tagsToDelete, viewToRemove.getId())) {
432439
// The view will be removed and dropped by the 'delete' layout animation
433440
// instead, so do nothing
@@ -476,7 +483,8 @@ public synchronized void manageChildren(
476483
tagsToDelete));
477484
}
478485

479-
if (mLayoutAnimator.shouldAnimateLayout(viewToDestroy)) {
486+
if (mLayoutAnimationEnabled &&
487+
mLayoutAnimator.shouldAnimateLayout(viewToDestroy)) {
480488
int updatedCount = pendingIndicesToDelete.get(indexToDelete, 0) + 1;
481489
pendingIndicesToDelete.put(indexToDelete, updatedCount);
482490
mLayoutAnimator.deleteView(

Diff for: ReactAndroid/src/main/java/com/facebook/react/uimanager/UIImplementation.java

+15
Original file line numberDiff line numberDiff line change
@@ -693,6 +693,21 @@ protected void updateViewHierarchy() {
693693
}
694694
}
695695

696+
/**
697+
* LayoutAnimation API on Android is currently experimental. Therefore, it needs to be enabled
698+
* explicitly in order to avoid regression in existing application written for iOS using this API.
699+
*
700+
* Warning : This method will be removed in future version of React Native, and layout animation
701+
* will be enabled by default, so always check for its existence before invoking it.
702+
*
703+
* TODO(9139831) : remove this method once layout animation is fully stable.
704+
*
705+
* @param enabled whether layout animation is enabled or not
706+
*/
707+
public void setLayoutAnimationEnabledExperimental(boolean enabled) {
708+
mOperationsQueue.enqueueSetLayoutAnimationEnabled(enabled);
709+
}
710+
696711
/**
697712
* Configure an animation to be used for the native layout changes, and native views
698713
* creation. The animation will only apply during the current batch operations.

Diff for: ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModule.java

+16
Original file line numberDiff line numberDiff line change
@@ -689,6 +689,22 @@ public void dismissPopupMenu() {
689689
mUIImplementation.dismissPopupMenu();
690690
}
691691

692+
/**
693+
* LayoutAnimation API on Android is currently experimental. Therefore, it needs to be enabled
694+
* explicitly in order to avoid regression in existing application written for iOS using this API.
695+
*
696+
* <p>Warning : This method will be removed in future version of React Native, and layout
697+
* animation will be enabled by default, so always check for its existence before invoking it.
698+
*
699+
* <p>TODO(9139831) : remove this method once layout animation is fully stable.
700+
*
701+
* @param enabled whether layout animation is enabled or not
702+
*/
703+
@ReactMethod
704+
public void setLayoutAnimationEnabledExperimental(boolean enabled) {
705+
mUIImplementation.setLayoutAnimationEnabledExperimental(enabled);
706+
}
707+
692708
/**
693709
* Configure an animation to be used for the native layout changes, and native views creation. The
694710
* animation will only apply during the current batch operations.

Diff for: ReactAndroid/src/main/java/com/facebook/react/uimanager/UIViewOperationQueue.java

+18
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,19 @@ public AnimationOperation(int animationID) {
354354
}
355355
}
356356

357+
private class SetLayoutAnimationEnabledOperation implements UIOperation {
358+
private final boolean mEnabled;
359+
360+
private SetLayoutAnimationEnabledOperation(final boolean enabled) {
361+
mEnabled = enabled;
362+
}
363+
364+
@Override
365+
public void execute() {
366+
mNativeViewHierarchyManager.setLayoutAnimationEnabled(mEnabled);
367+
}
368+
}
369+
357370
private class ConfigureLayoutAnimationOperation implements UIOperation {
358371
private final ReadableMap mConfig;
359372
private final Callback mAnimationComplete;
@@ -723,6 +736,11 @@ public void enqueueSetChildren(
723736
new SetChildrenOperation(reactTag, childrenTags));
724737
}
725738

739+
public void enqueueSetLayoutAnimationEnabled(
740+
final boolean enabled) {
741+
mOperations.add(new SetLayoutAnimationEnabledOperation(enabled));
742+
}
743+
726744
public void enqueueConfigureLayoutAnimation(
727745
final ReadableMap config,
728746
final Callback onAnimationComplete) {

0 commit comments

Comments
 (0)