From 241fd0869d9634c4103f0c5caa5b4f9b3aea972d Mon Sep 17 00:00:00 2001 From: Ahmed El-Helw Date: Thu, 16 Jun 2016 18:01:58 -0700 Subject: [PATCH] Fix autoFocus for TextInput Summary: During the patch for fixing the order of UI operations, we apply updates to any node receiving a ViewManager command in order to ensure that nodes that were not yet mounted to a View and not yet attached to their parent would be properly able to receive the event. However, if a node is already a view, calling the update could cause unwanted things to happen (for example, the View's bounds changing improperly), because we're only traversing that node of the tree and down (instead of the entire tree). This fixes the issue by only applying updates to the node if the view mount state has changed. Reviewed By: sriramramani Differential Revision: D3448356 --- .../react/flat/FlatUIImplementation.java | 20 ++++++++++++------- .../com/facebook/react/flat/StateBuilder.java | 5 +++-- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/flat/FlatUIImplementation.java b/ReactAndroid/src/main/java/com/facebook/react/flat/FlatUIImplementation.java index 8aa07d036..a45ddca63 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/flat/FlatUIImplementation.java +++ b/ReactAndroid/src/main/java/com/facebook/react/flat/FlatUIImplementation.java @@ -217,10 +217,12 @@ public class FlatUIImplementation extends UIImplementation { callback); } - private void ensureMountsToViewAndBackingViewIsCreated(int reactTag) { + private boolean ensureMountsToViewAndBackingViewIsCreated(int reactTag) { FlatShadowNode node = (FlatShadowNode) resolveShadowNode(reactTag); + boolean didUpdate = !node.mountsToView(); node.forceMountToView(); - mStateBuilder.ensureBackingViewIsCreated(node); + didUpdate = didUpdate || mStateBuilder.ensureBackingViewIsCreated(node); + return didUpdate; } @Override @@ -243,11 +245,15 @@ public class FlatUIImplementation extends UIImplementation { @Override public void dispatchViewManagerCommand(int reactTag, int commandId, ReadableArray commandArgs) { - ensureMountsToViewAndBackingViewIsCreated(reactTag); - // need to make sure any ui operations (UpdateViewGroup, for example, etc) have already - // happened before we actually dispatch the view manager command (since otherwise, the command - // may go to an empty shell parent without its children, which is against the specs). - mStateBuilder.applyUpdates((FlatShadowNode) resolveShadowNode(reactTag)); + if (ensureMountsToViewAndBackingViewIsCreated(reactTag)) { + // need to make sure any ui operations (UpdateViewGroup, for example, etc) have already + // happened before we actually dispatch the view manager command (since otherwise, the command + // may go to an empty shell parent without its children, which is against the specs). note + // that we only want to applyUpdates if the view has not yet been created so that it does + // get created (otherwise, we may end up changing the View's position when we're not supposed + // to, for example). + mStateBuilder.applyUpdates((FlatShadowNode) resolveShadowNode(reactTag)); + } super.dispatchViewManagerCommand(reactTag, commandId, commandArgs); } diff --git a/ReactAndroid/src/main/java/com/facebook/react/flat/StateBuilder.java b/ReactAndroid/src/main/java/com/facebook/react/flat/StateBuilder.java index 167d4cf22..f5972247a 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/flat/StateBuilder.java +++ b/ReactAndroid/src/main/java/com/facebook/react/flat/StateBuilder.java @@ -147,15 +147,16 @@ import com.facebook.react.uimanager.events.EventDispatcher; mStylesToUpdate.add(styles); } - /* package */ void ensureBackingViewIsCreated(FlatShadowNode node) { + /* package */ boolean ensureBackingViewIsCreated(FlatShadowNode node) { if (node.isBackingViewCreated()) { - return; + return false; } int tag = node.getReactTag(); mOperationsQueue.enqueueCreateView(node.getThemedContext(), tag, node.getViewClass(), null); node.signalBackingViewIsCreated(); + return true; } /* package */ void dropView(FlatShadowNode node) {