Fix for ViewManager commands being run before view updates.

Summary: Since Nodes' manageChildren doesn't enqueue the child updates immediately, commands were being directed to non-updated views.  Previously we applied updates for the shadow node before dispatching the command, but we can instead wait to fire commands until after we update the view hierarchy.

Reviewed By: ahmedre

Differential Revision: D3568541
This commit is contained in:
Seth Kirby
2016-12-19 13:40:28 -08:00
committed by Ahmed El-Helw
parent 7df627f9be
commit 95ae936aa6
3 changed files with 64 additions and 15 deletions
@@ -17,6 +17,7 @@ import android.view.ViewGroup;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.uimanager.IllegalViewOperationException;
import com.facebook.react.uimanager.NoSuchNativeViewException;
import com.facebook.react.uimanager.PixelUtil;
@@ -314,6 +315,31 @@ import com.facebook.react.uimanager.UIViewOperationQueue;
}
}
/**
* Used to delay view manager command dispatch until after the view hierarchy is updated.
* Mirrors command operation dispatch, but is only used in Nodes for view manager commands.
*/
public final class ViewManagerCommand implements UIOperation {
private final int mReactTag;
private final int mCommand;
private final @Nullable ReadableArray mArgs;
public ViewManagerCommand(
int reactTag,
int command,
@Nullable ReadableArray args) {
mReactTag = reactTag;
mCommand = command;
mArgs = args;
}
@Override
public void execute() {
mNativeViewHierarchyManager.dispatchCommand(mReactTag, mCommand, mArgs);
}
}
public FlatUIViewOperationQueue(
ReactApplicationContext reactContext,
FlatNativeViewHierarchyManager nativeViewHierarchyManager) {
@@ -359,6 +385,17 @@ import com.facebook.react.uimanager.UIViewOperationQueue;
enqueueUIOperation(updateViewBounds);
}
public ViewManagerCommand createViewManagerCommand(
int reactTag,
int command,
@Nullable ReadableArray args) {
return new ViewManagerCommand(reactTag, command, args);
}
public void enqueueViewManagerCommand(ViewManagerCommand viewManagerCommand) {
enqueueUIOperation(viewManagerCommand);
}
public void enqueueSetPadding(
int reactTag,
int paddingLeft,