From 76c2904d31504432089d502a9ebf4b9d00c5f497 Mon Sep 17 00:00:00 2001 From: Seth Kirby Date: Mon, 18 Jul 2016 21:18:32 -0700 Subject: [PATCH] Add support for WRAP_CONTENT to react views. Summary: Fixes needing to specify exact height of react views in Mason. Uses a ViewTreeObserver to delay draw until we have correct bounds. Reviewed By: sriramramani Differential Revision: D3527122 --- .../react/flat/FlatMeasuredViewGroup.java | 26 +++++++++++++++ .../facebook/react/flat/FlatViewGroup.java | 33 ++++++++++++++++++- 2 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 ReactAndroid/src/main/java/com/facebook/react/flat/FlatMeasuredViewGroup.java diff --git a/ReactAndroid/src/main/java/com/facebook/react/flat/FlatMeasuredViewGroup.java b/ReactAndroid/src/main/java/com/facebook/react/flat/FlatMeasuredViewGroup.java new file mode 100644 index 0000000000..573f8944f0 --- /dev/null +++ b/ReactAndroid/src/main/java/com/facebook/react/flat/FlatMeasuredViewGroup.java @@ -0,0 +1,26 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +package com.facebook.react.flat; + +import android.graphics.Rect; + +/** + * Helper interface to provide measuring of FlatViewGroup when needed. We don't override onMeasure + * for FlatViewGroup, which means that draw commands don't contributed to the measured width and + * height. This allows us to expose our calculated dimensions taking into account draw commands, + * without changing the visibility of the FlatViewGroup. + */ +public interface FlatMeasuredViewGroup { + /** + * @return A rect consisting of the left, top, right, and bottommost edge among all children, + * including draw commands. + */ + Rect measureWithCommands(); +} 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 419d546996..eb0a7b4ba8 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/flat/FlatViewGroup.java +++ b/ReactAndroid/src/main/java/com/facebook/react/flat/FlatViewGroup.java @@ -48,7 +48,7 @@ import com.facebook.react.views.view.ReactClippingViewGroupHelper; */ /* package */ final class FlatViewGroup extends ViewGroup implements ReactInterceptingViewGroup, ReactClippingViewGroup, - ReactCompoundViewGroup, ReactPointerEventsView { + ReactCompoundViewGroup, ReactPointerEventsView, FlatMeasuredViewGroup { /** * Helper class that allows AttachDetachListener to invalidate the hosting View. */ @@ -543,6 +543,37 @@ import com.facebook.react.views.view.ReactClippingViewGroupHelper; LAYOUT_REQUESTS.clear(); } + // Helper method for measure functionality provided by MeasuredViewGroup. + @Override + public Rect measureWithCommands() { + int childCount = getChildCount(); + if (childCount == 0 && mDrawCommands.length == 0) { + return new Rect(0, 0, 0, 0); + } + int left = Integer.MAX_VALUE; + int top = Integer.MAX_VALUE; + int right = Integer.MIN_VALUE; + int bottom = Integer.MIN_VALUE; + for (int i = 0; i < childCount; i++) { + View child = getChildAt(i); + left = Math.min(left, child.getLeft()); + top = Math.min(top, child.getTop()); + right = Math.max(right, child.getRight()); + bottom = Math.max(bottom, child.getBottom()); + } + for (int i = 0; i < mDrawCommands.length; i++) { + if (!(mDrawCommands[i] instanceof AbstractDrawCommand)) { + continue; + } + AbstractDrawCommand drawCommand = (AbstractDrawCommand) mDrawCommands[i]; + left = Math.min(left, Math.round(drawCommand.getLeft())); + top = Math.min(top, Math.round(drawCommand.getTop())); + right = Math.max(right, Math.round(drawCommand.getRight())); + bottom = Math.max(bottom, Math.round(drawCommand.getBottom())); + } + return new Rect(left, top, right, bottom); + } + private @Nullable NodeRegion virtualNodeRegionWithinBounds(float touchX, float touchY) { for (int i = mNodeRegions.length - 1; i >= 0; --i) { NodeRegion nodeRegion = mNodeRegions[i];