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
This commit is contained in:
Ahmed El-Helw 2016-06-16 18:01:58 -07:00
parent f0734c141f
commit 241fd0869d
2 changed files with 16 additions and 9 deletions

View File

@ -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);
}

View File

@ -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) {