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
This commit is contained in:
Seth Kirby 2016-07-18 21:18:32 -07:00 committed by Ahmed El-Helw
parent 6cc6cd4d44
commit 76c2904d31
2 changed files with 58 additions and 1 deletions

View File

@ -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();
}

View File

@ -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];