diff --git a/ReactAndroid/src/main/java/com/facebook/react/flat/FlatUIViewOperationQueue.java b/ReactAndroid/src/main/java/com/facebook/react/flat/FlatUIViewOperationQueue.java index de18b70bd..7175633d6 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/flat/FlatUIViewOperationQueue.java +++ b/ReactAndroid/src/main/java/com/facebook/react/flat/FlatUIViewOperationQueue.java @@ -21,6 +21,14 @@ import com.facebook.react.uimanager.UIViewOperationQueue; /* package */ final class FlatUIViewOperationQueue extends UIViewOperationQueue { private final FlatNativeViewHierarchyManager mNativeViewHierarchyManager; + private final ProcessLayoutRequests mProcessLayoutRequests = new ProcessLayoutRequests(); + + private final class ProcessLayoutRequests implements UIOperation { + @Override + public void execute() { + FlatViewGroup.processLayoutRequests(); + } + } /** * UIOperation that updates DrawCommands for a View defined by reactTag. @@ -199,6 +207,10 @@ import com.facebook.react.uimanager.UIViewOperationQueue; enqueueUIOperation(new DropViews(viewsToDrop)); } + public void enqueueProcessLayoutRequests() { + enqueueUIOperation(mProcessLayoutRequests); + } + public DetachAllChildrenFromViews enqueueDetachAllChildrenFromViews() { DetachAllChildrenFromViews op = new DetachAllChildrenFromViews(); enqueueUIOperation(op); diff --git a/ReactAndroid/src/main/java/com/facebook/react/flat/FlatViewGroup.java b/ReactAndroid/src/main/java/com/facebook/react/flat/FlatViewGroup.java index feb446935..b4157b54a 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/flat/FlatViewGroup.java +++ b/ReactAndroid/src/main/java/com/facebook/react/flat/FlatViewGroup.java @@ -10,6 +10,7 @@ package com.facebook.react.flat; import java.lang.ref.WeakReference; +import java.util.ArrayList; import javax.annotation.Nullable; @@ -46,12 +47,15 @@ import com.facebook.react.uimanager.ReactCompoundView; } } + private static final ArrayList LAYOUT_REQUESTS = new ArrayList<>(); + private @Nullable InvalidateCallback mInvalidateCallback; private DrawCommand[] mDrawCommands = DrawCommand.EMPTY_ARRAY; private AttachDetachListener[] mAttachDetachListeners = AttachDetachListener.EMPTY_ARRAY; private NodeRegion[] mNodeRegions = NodeRegion.EMPTY_ARRAY; private int mDrawChildIndex = 0; private boolean mIsAttached = false; + private boolean mIsLayoutRequested = false; /* package */ FlatViewGroup(Context context) { super(context); @@ -62,6 +66,16 @@ import com.facebook.react.uimanager.ReactCompoundView; super.detachAllViewsFromParent(); } + @Override + public void requestLayout() { + if (mIsLayoutRequested) { + return; + } + + mIsLayoutRequested = true; + LAYOUT_REQUESTS.add(this); + } + @Override public int reactTagForTouch(float touchX, float touchY) { for (NodeRegion nodeRegion : mNodeRegions) { @@ -167,7 +181,7 @@ import com.facebook.react.uimanager.ReactCompoundView; for (int viewToAdd : viewsToAdd) { if (viewToAdd > 0) { View view = ensureViewHasNoParent(viewResolver.getView(viewToAdd)); - addView(view, -1, ensureLayoutParams(view.getLayoutParams())); + addViewInLayout(view, -1, ensureLayoutParams(view.getLayoutParams()), true); } else { View view = ensureViewHasNoParent(viewResolver.getView(-viewToAdd)); attachViewToParent(view, -1, ensureLayoutParams(view.getLayoutParams())); @@ -179,6 +193,29 @@ import com.facebook.react.uimanager.ReactCompoundView; } } + /* package */ void processLayoutRequest() { + mIsLayoutRequested = false; + for (int i = 0, childCount = getChildCount(); i != childCount; ++i) { + View child = getChildAt(i); + if (!child.isLayoutRequested()) { + continue; + } + + child.measure( + MeasureSpec.makeMeasureSpec(child.getWidth(), MeasureSpec.EXACTLY), + MeasureSpec.makeMeasureSpec(child.getHeight(), MeasureSpec.EXACTLY)); + child.layout(child.getLeft(), child.getTop(), child.getRight(), child.getBottom()); + } + } + + /* package */ static void processLayoutRequests() { + for (int i = 0, numLayoutRequests = LAYOUT_REQUESTS.size(); i != numLayoutRequests; ++i) { + FlatViewGroup flatViewGroup = LAYOUT_REQUESTS.get(i); + flatViewGroup.processLayoutRequest(); + } + LAYOUT_REQUESTS.clear(); + } + private View ensureViewHasNoParent(View view) { ViewParent oldParent = view.getParent(); if (oldParent != null) { 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 ccce7b24a..3875f01de 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/flat/StateBuilder.java +++ b/ReactAndroid/src/main/java/com/facebook/react/flat/StateBuilder.java @@ -84,6 +84,8 @@ import com.facebook.react.uimanager.CatalystStylesDiffMap; mOperationsQueue.enqueueDropViews(collectViewTags(mViewsToDrop)); mViewsToDrop.clear(); } + + mOperationsQueue.enqueueProcessLayoutRequests(); } /**