From 312f04d2b782aeb3f9f6bd6c75a4c64e0a0f0b8e Mon Sep 17 00:00:00 2001 From: Denis Koroskin Date: Tue, 15 Dec 2015 22:09:17 -0800 Subject: [PATCH] Apply FlatShadowNode padding to View Summary: Any padding that a FlatShadowNode is assigned by React runtime should be translated to a backing Android View so it looks correct and lays out children accordingly. Reviewed By: sriramramani Differential Revision: D2756562 --- .../com/facebook/react/flat/AndroidView.java | 17 ++++++++ .../flat/FlatNativeViewHierarchyManager.java | 9 ++++ .../react/flat/FlatUIViewOperationQueue.java | 42 +++++++++++++++++++ .../com/facebook/react/flat/StateBuilder.java | 19 ++++++++- 4 files changed, 86 insertions(+), 1 deletion(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/flat/AndroidView.java b/ReactAndroid/src/main/java/com/facebook/react/flat/AndroidView.java index 14bc87437..0d6273f50 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/flat/AndroidView.java +++ b/ReactAndroid/src/main/java/com/facebook/react/flat/AndroidView.java @@ -21,6 +21,7 @@ import com.facebook.react.uimanager.ViewManager; final ViewManager mViewManager; private final ReactShadowNode mReactShadowNode; private final boolean mNeedsCustomLayoutForChildren; + private boolean mPaddingChanged = false; /* package */ AndroidView(ViewManager viewManager) { mViewManager = viewManager; @@ -46,6 +47,14 @@ import com.facebook.react.uimanager.ViewManager; return mNeedsCustomLayoutForChildren; } + /* package */ boolean isPaddingChanged() { + return mPaddingChanged; + } + + /* package */ void resetPaddingChanged() { + mPaddingChanged = false; + } + @Override public void setBackgroundColor(int backgroundColor) { // suppress, this is handled by a ViewManager @@ -72,4 +81,12 @@ import com.facebook.react.uimanager.ViewManager; super.addChildAt(child, i); ((FlatShadowNode) child).forceMountToView(); } + + @Override + public void setPadding(int spacingType, float padding) { + if (getPadding().set(spacingType, padding)) { + mPaddingChanged = true; + dirty(); + } + } } diff --git a/ReactAndroid/src/main/java/com/facebook/react/flat/FlatNativeViewHierarchyManager.java b/ReactAndroid/src/main/java/com/facebook/react/flat/FlatNativeViewHierarchyManager.java index 37b454012..a8f44a960 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/flat/FlatNativeViewHierarchyManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/flat/FlatNativeViewHierarchyManager.java @@ -113,6 +113,15 @@ import com.facebook.react.uimanager.ViewManagerRegistry; } } + /* package */ void setPadding( + int reactTag, + int paddingLeft, + int paddingTop, + int paddingRight, + int paddingBottom) { + resolveView(reactTag).setPadding(paddingLeft, paddingTop, paddingRight, paddingBottom); + } + /* package */ void detachAllChildrenFromViews(int[] viewsToDetachAllChildrenFrom) { for (int viewTag : viewsToDetachAllChildrenFrom) { View view = resolveView(viewTag); 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 8d12561ee..0c829d327 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/flat/FlatUIViewOperationQueue.java +++ b/ReactAndroid/src/main/java/com/facebook/react/flat/FlatUIViewOperationQueue.java @@ -96,6 +96,38 @@ import com.facebook.react.uimanager.UIViewOperationQueue; } } + private final class SetPadding implements UIOperation { + + private final int mReactTag; + private final int mPaddingLeft; + private final int mPaddingTop; + private final int mPaddingRight; + private final int mPaddingBottom; + + private SetPadding( + int reactTag, + int paddingLeft, + int paddingTop, + int paddingRight, + int paddingBottom) { + mReactTag = reactTag; + mPaddingLeft = paddingLeft; + mPaddingTop = paddingTop; + mPaddingRight = paddingRight; + mPaddingBottom = paddingBottom; + } + + @Override + public void execute() { + mNativeViewHierarchyManager.setPadding( + mReactTag, + mPaddingLeft, + mPaddingTop, + mPaddingRight, + mPaddingBottom); + } + } + public final class DetachAllChildrenFromViews implements UIViewOperationQueue.UIOperation { private @Nullable int[] mViewsToDetachAllChildrenFrom; @@ -139,6 +171,16 @@ import com.facebook.react.uimanager.UIViewOperationQueue; enqueueUIOperation(new UpdateViewBounds(reactTag, left, top, right, bottom)); } + public void enqueueSetPadding( + int reactTag, + int paddingLeft, + int paddingTop, + int paddingRight, + int paddingBottom) { + enqueueUIOperation( + new SetPadding(reactTag, paddingLeft, paddingTop, paddingRight, paddingBottom)); + } + public DetachAllChildrenFromViews enqueueDetachAllChildrenFromViews() { DetachAllChildrenFromViews op = new DetachAllChildrenFromViews(); enqueueUIOperation(op); 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 97eebb79f..97e34aa00 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/flat/StateBuilder.java +++ b/ReactAndroid/src/main/java/com/facebook/react/flat/StateBuilder.java @@ -13,6 +13,7 @@ import java.util.ArrayList; import javax.annotation.Nullable; +import com.facebook.csslayout.Spacing; import com.facebook.react.uimanager.CatalystStylesDiffMap; /** @@ -152,8 +153,11 @@ import com.facebook.react.uimanager.CatalystStylesDiffMap; boolean isAndroidView = false; boolean needsCustomLayoutForChildren = false; if (node instanceof AndroidView) { + AndroidView androidView = (AndroidView) node; + updateViewPadding(androidView, tag); + isAndroidView = true; - needsCustomLayoutForChildren = ((AndroidView) node).needsCustomLayoutForChildren(); + needsCustomLayoutForChildren = androidView.needsCustomLayoutForChildren(); } collectStateRecursively(node, 0, 0, width, height, isAndroidView, needsCustomLayoutForChildren); @@ -324,6 +328,19 @@ import com.facebook.react.uimanager.CatalystStylesDiffMap; } } + private void updateViewPadding(AndroidView androidView, int tag) { + if (androidView.isPaddingChanged()) { + Spacing padding = androidView.getPadding(); + mOperationsQueue.enqueueSetPadding( + tag, + Math.round(padding.get(Spacing.LEFT)), + Math.round(padding.get(Spacing.TOP)), + Math.round(padding.get(Spacing.RIGHT)), + Math.round(padding.get(Spacing.BOTTOM))); + androidView.resetPaddingChanged(); + } + } + private static int[] collectViewTags(ArrayList views) { int numViews = views.size(); if (numViews == 0) {