From 4fb42be0a1efff3eecdb8023241178e1f872f840 Mon Sep 17 00:00:00 2001 From: Denis Koroskin Date: Sun, 13 Dec 2015 21:00:20 -0800 Subject: [PATCH] Dispatch View bounds updates at the end of StateBuilder.applyUpdates() Summary: Normally, order or `measure/layout` and `onAttachedToWindow` shouldn't matter. However, `DrawerLayout` has a `boolean mFirstLayout` flag that it resets to true in `onAttachedToWindow` that makes it ignore first layout, and it leads to bugs. To fix the issue, we need to make sure that we first call `onAttachedToWindow` and only then we call `measure/layout`. The easiest way to do it is to delay measure/layout calls until all the views are attached to their parents. This diff implements the mentioned logic. Reviewed By: sriramramani Differential Revision: D2694973 --- .../com/facebook/react/flat/StateBuilder.java | 29 ++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) 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 791768cf4..bc1dd9e3c 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/flat/StateBuilder.java +++ b/ReactAndroid/src/main/java/com/facebook/react/flat/StateBuilder.java @@ -38,6 +38,7 @@ import com.facebook.react.uimanager.CatalystStylesDiffMap; private final ArrayList mViewsToDetachAllChildrenFrom = new ArrayList<>(); private final ArrayList mViewsToDetach = new ArrayList<>(); + private final ArrayList mViewsToUpdateBounds = new ArrayList<>(); private @Nullable FlatUIViewOperationQueue.DetachAllChildrenFromViews mDetachAllChildrenFromViews; @@ -61,7 +62,8 @@ import com.facebook.react.uimanager.CatalystStylesDiffMap; float right = left + width; float bottom = top + height; updateNodeRegion(node, tag, left, top, right, bottom); - updateViewBounds(node, tag, left, top, right, bottom); + + mViewsToUpdateBounds.add(node); if (mDetachAllChildrenFromViews != null) { int[] viewsToDetachAllChildrenFrom = collectViewTags(mViewsToDetachAllChildrenFrom); @@ -70,6 +72,11 @@ import com.facebook.react.uimanager.CatalystStylesDiffMap; mDetachAllChildrenFromViews.setViewsToDetachAllChildrenFrom(viewsToDetachAllChildrenFrom); mDetachAllChildrenFromViews = null; } + + for (int i = 0, size = mViewsToUpdateBounds.size(); i != size; ++i) { + updateViewBounds(mViewsToUpdateBounds.get(i)); + } + mViewsToUpdateBounds.clear(); } /** @@ -110,18 +117,13 @@ import com.facebook.react.uimanager.CatalystStylesDiffMap; /** * Updates boundaries of a View that a give nodes maps to. */ - private void updateViewBounds( - FlatShadowNode node, - int tag, - float leftInParent, - float topInParent, - float rightInParent, - float bottomInParent) { - int viewLeft = Math.round(leftInParent); - int viewTop = Math.round(topInParent); - int viewRight = Math.round(rightInParent); - int viewBottom = Math.round(bottomInParent); + private void updateViewBounds(FlatShadowNode node) { + NodeRegion nodeRegion = node.getNodeRegion(); + int viewLeft = Math.round(nodeRegion.mLeft); + int viewTop = Math.round(nodeRegion.mTop); + int viewRight = Math.round(nodeRegion.mRight); + int viewBottom = Math.round(nodeRegion.mBottom); if (node.getViewLeft() == viewLeft && node.getViewTop() == viewTop && node.getViewRight() == viewRight && node.getViewBottom() == viewBottom) { // nothing changed. @@ -130,6 +132,7 @@ import com.facebook.react.uimanager.CatalystStylesDiffMap; // this will optionally measure and layout the View this node maps to. node.setViewBounds(viewLeft, viewTop, viewRight, viewBottom); + int tag = node.getReactTag(); mOperationsQueue.enqueueUpdateViewBounds(tag, viewLeft, viewTop, viewRight, viewBottom); } @@ -284,7 +287,7 @@ import com.facebook.react.uimanager.CatalystStylesDiffMap; mDrawCommands.add(DrawView.INSTANCE); collectStateForMountableNode(node, tag, width, height); - updateViewBounds(node, tag, left, top, right, bottom); + mViewsToUpdateBounds.add(node); } else { collectStateRecursively(node, left, top, right, bottom); addNodeRegion(node.getNodeRegion());