From b81c8b51fc6fe3c2dece72e3fe500e175613c5d4 Mon Sep 17 00:00:00 2001 From: Tim Yung Date: Fri, 29 Jun 2018 12:07:02 -0700 Subject: [PATCH] RN: Add Support for `overflow` on Android (Take 2) Summary: Adds support for the `overflow` style property on React Native for Android. This is the second attempt to do this. See https://github.com/facebook/react-native/commit/6110a4cc75bf8f285ff091cc175b9ebf737f88fc (D8666509) for the first attempt. Similar to the first attempt, this sets `setClipChildren(false)` by default on all `ViewGroup` instances. However, this differs in how it implements `overflow: hidden`. Instead of conditionally setting `setClipChildren`, this manually clips children to the `ViewGroup`'s bounds (which was incidentally what we were doing for background + border radius already). Reviewed By: achen1 Differential Revision: D8690805 fbshipit-source-id: 58757825cd9d138c18c8758918d85b4ca1915f87 --- .../facebook/react/uimanager/ViewProps.java | 11 +++++----- .../react/views/view/ReactViewGroup.java | 20 ++++++++++++------- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewProps.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewProps.java index 11f09b0b68053d..29ed6e96c0e0d0 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewProps.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewProps.java @@ -24,7 +24,6 @@ public class ViewProps { public static final String ALIGN_ITEMS = "alignItems"; public static final String ALIGN_SELF = "alignSelf"; public static final String ALIGN_CONTENT = "alignContent"; - public static final String OVERFLOW = "overflow"; public static final String DISPLAY = "display"; public static final String BOTTOM = "bottom"; public static final String COLLAPSABLE = "collapsable"; @@ -74,9 +73,6 @@ public class ViewProps { public static final String MIN_HEIGHT = "minHeight"; public static final String MAX_HEIGHT = "maxHeight"; - public static final String HIDDEN = "hidden"; - public static final String VISIBLE = "visible"; - public static final String ASPECT_RATIO = "aspectRatio"; // Props that sometimes may prevent us from collapsing views @@ -103,6 +99,10 @@ public class ViewProps { public static final String TEXT_DECORATION_LINE = "textDecorationLine"; public static final String TEXT_BREAK_STRATEGY = "textBreakStrategy"; public static final String OPACITY = "opacity"; + public static final String OVERFLOW = "overflow"; + + public static final String HIDDEN = "hidden"; + public static final String VISIBLE = "visible"; public static final String ALLOW_FONT_SCALING = "allowFontScaling"; public static final String INCLUDE_FONT_PADDING = "includeFontPadding"; @@ -169,7 +169,6 @@ public class ViewProps { FLEX_SHRINK, FLEX_WRAP, JUSTIFY_CONTENT, - OVERFLOW, ALIGN_CONTENT, DISPLAY, @@ -257,6 +256,8 @@ public static boolean isLayoutOnly(ReadableMap map, String prop) { return map.isNull(BORDER_RIGHT_WIDTH) || map.getDouble(BORDER_RIGHT_WIDTH) == 0d; case BORDER_BOTTOM_WIDTH: return map.isNull(BORDER_BOTTOM_WIDTH) || map.getDouble(BORDER_BOTTOM_WIDTH) == 0d; + case OVERFLOW: + return map.isNull(OVERFLOW) || VISIBLE.equals(map.getString(OVERFLOW)); default: return false; } diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.java b/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.java index 8d6a2abea8c114..bdd522bd2a60ad 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.java @@ -113,6 +113,7 @@ public void onLayoutChange( public ReactViewGroup(Context context) { super(context); + setClipChildren(false); mDrawingOrderHelper = new ViewGroupDrawingOrderHelper(this); } @@ -689,12 +690,14 @@ private void dispatchOverflowDraw(Canvas canvas) { } break; case ViewProps.HIDDEN: - if (mReactBackgroundDrawable != null) { - float left = 0f; - float top = 0f; - float right = getWidth(); - float bottom = getHeight(); + float left = 0f; + float top = 0f; + float right = getWidth(); + float bottom = getHeight(); + + boolean hasClipPath = false; + if (mReactBackgroundDrawable != null) { final RectF borderWidth = mReactBackgroundDrawable.getDirectionAwareBorderInsets(); if (borderWidth.top > 0 @@ -817,10 +820,13 @@ private void dispatchOverflowDraw(Canvas canvas) { }, Path.Direction.CW); canvas.clipPath(mPath); - } else { - canvas.clipRect(new RectF(left, top, right, bottom)); + hasClipPath = true; } } + + if (!hasClipPath) { + canvas.clipRect(new RectF(left, top, right, bottom)); + } break; default: break;