mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
e380d6d0fd
Summary: Before this patch, each Node would always generate a node region, representing the bounds of this particular Node. This set of Nodes was used when handling touch to figure out whether we should intercept touch (i.e. a flat Node is catching the draw), or let Android handle touch (i.e. a Node mounted to a View will handle the touch). This patch modifies the list of NodeRegions to exclude any Nodes that draw nothing at all. These Nodes, having no draw output, are effectively layout containers used to group items, so they shouldn't handle touch. Reviewed By: sriramramani Differential Revision: D4369484 fbshipit-source-id: 71b41611873580631f1639f368fa8d971995874f
188 lines
5.3 KiB
Java
188 lines
5.3 KiB
Java
/**
|
|
* 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 javax.annotation.Nullable;
|
|
|
|
import android.graphics.Rect;
|
|
|
|
import com.facebook.react.bridge.ReadableMap;
|
|
import com.facebook.react.uimanager.PixelUtil;
|
|
import com.facebook.react.uimanager.Spacing;
|
|
import com.facebook.react.uimanager.ReactStylesDiffMap;
|
|
import com.facebook.react.uimanager.annotations.ReactProp;
|
|
import com.facebook.react.uimanager.annotations.ReactPropGroup;
|
|
|
|
/**
|
|
* Node for a react View.
|
|
*/
|
|
/* package */ final class RCTView extends FlatShadowNode {
|
|
private static final int[] SPACING_TYPES = {
|
|
Spacing.ALL, Spacing.LEFT, Spacing.RIGHT, Spacing.TOP, Spacing.BOTTOM,
|
|
};
|
|
|
|
private @Nullable DrawBorder mDrawBorder;
|
|
|
|
boolean mRemoveClippedSubviews;
|
|
boolean mHorizontal;
|
|
|
|
private @Nullable Rect mHitSlop;
|
|
|
|
@Override
|
|
/* package */ void handleUpdateProperties(ReactStylesDiffMap styles) {
|
|
mRemoveClippedSubviews = mRemoveClippedSubviews ||
|
|
(styles.hasKey(PROP_REMOVE_CLIPPED_SUBVIEWS) &&
|
|
styles.getBoolean(PROP_REMOVE_CLIPPED_SUBVIEWS, false));
|
|
|
|
if (mRemoveClippedSubviews) {
|
|
mHorizontal = mHorizontal ||
|
|
(styles.hasKey(PROP_HORIZONTAL) && styles.getBoolean(PROP_HORIZONTAL, false));
|
|
}
|
|
|
|
super.handleUpdateProperties(styles);
|
|
}
|
|
|
|
@Override
|
|
protected void collectState(
|
|
StateBuilder stateBuilder,
|
|
float left,
|
|
float top,
|
|
float right,
|
|
float bottom,
|
|
float clipLeft,
|
|
float clipTop,
|
|
float clipRight,
|
|
float clipBottom) {
|
|
super.collectState(
|
|
stateBuilder,
|
|
left,
|
|
top,
|
|
right,
|
|
bottom,
|
|
clipLeft,
|
|
clipTop,
|
|
clipRight,
|
|
clipBottom);
|
|
|
|
if (mDrawBorder != null) {
|
|
mDrawBorder = (DrawBorder) mDrawBorder.updateBoundsAndFreeze(
|
|
left,
|
|
top,
|
|
right,
|
|
bottom,
|
|
clipLeft,
|
|
clipTop,
|
|
clipRight,
|
|
clipBottom);
|
|
stateBuilder.addDrawCommand(mDrawBorder);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
boolean doesDraw() {
|
|
return mDrawBorder != null || super.doesDraw();
|
|
}
|
|
|
|
@Override
|
|
public void setBackgroundColor(int backgroundColor) {
|
|
getMutableBorder().setBackgroundColor(backgroundColor);
|
|
}
|
|
|
|
@Override
|
|
public void setBorderWidths(int index, float borderWidth) {
|
|
super.setBorderWidths(index, borderWidth);
|
|
|
|
int type = SPACING_TYPES[index];
|
|
getMutableBorder().setBorderWidth(type, PixelUtil.toPixelFromDIP(borderWidth));
|
|
}
|
|
|
|
@ReactProp(name = "nativeBackgroundAndroid")
|
|
public void setHotspot(@Nullable ReadableMap bg) {
|
|
if (bg != null) {
|
|
forceMountToView();
|
|
}
|
|
}
|
|
|
|
@ReactPropGroup(names = {
|
|
"borderColor", "borderLeftColor", "borderRightColor", "borderTopColor", "borderBottomColor"
|
|
}, customType = "Color", defaultDouble = Double.NaN)
|
|
public void setBorderColor(int index, double color) {
|
|
int type = SPACING_TYPES[index];
|
|
if (Double.isNaN(color)) {
|
|
getMutableBorder().resetBorderColor(type);
|
|
} else {
|
|
getMutableBorder().setBorderColor(type, (int) color);
|
|
}
|
|
}
|
|
|
|
@ReactProp(name = "borderRadius")
|
|
public void setBorderRadius(float borderRadius) {
|
|
mClipRadius = borderRadius;
|
|
if (mClipToBounds && borderRadius > DrawView.MINIMUM_ROUNDED_CLIPPING_VALUE) {
|
|
// mount to a view if we are overflow: hidden and are clipping, so that we can do one
|
|
// clipPath to clip all the children of this node (both DrawCommands and Views).
|
|
forceMountToView();
|
|
}
|
|
getMutableBorder().setBorderRadius(PixelUtil.toPixelFromDIP(borderRadius));
|
|
}
|
|
|
|
@ReactProp(name = "borderStyle")
|
|
public void setBorderStyle(@Nullable String borderStyle) {
|
|
getMutableBorder().setBorderStyle(borderStyle);
|
|
}
|
|
|
|
@ReactProp(name = "hitSlop")
|
|
public void setHitSlop(@Nullable ReadableMap hitSlop) {
|
|
if (hitSlop == null) {
|
|
mHitSlop = null;
|
|
} else {
|
|
mHitSlop = new Rect(
|
|
(int) PixelUtil.toPixelFromDIP(hitSlop.getDouble("left")),
|
|
(int) PixelUtil.toPixelFromDIP(hitSlop.getDouble("top")),
|
|
(int) PixelUtil.toPixelFromDIP(hitSlop.getDouble("right")),
|
|
(int) PixelUtil.toPixelFromDIP(hitSlop.getDouble("bottom")));
|
|
}
|
|
}
|
|
|
|
@ReactProp(name = "pointerEvents")
|
|
public void setPointerEvents(@Nullable String pointerEventsStr) {
|
|
forceMountToView();
|
|
}
|
|
|
|
@Override
|
|
/* package */ void updateNodeRegion(
|
|
float left,
|
|
float top,
|
|
float right,
|
|
float bottom,
|
|
boolean isVirtual) {
|
|
if (!getNodeRegion().matches(left, top, right, bottom, isVirtual)) {
|
|
setNodeRegion(mHitSlop == null ?
|
|
new NodeRegion(left, top, right, bottom, getReactTag(), isVirtual) :
|
|
new HitSlopNodeRegion(mHitSlop, left, top, right, bottom, getReactTag(), isVirtual));
|
|
}
|
|
}
|
|
|
|
private DrawBorder getMutableBorder() {
|
|
if (mDrawBorder == null) {
|
|
mDrawBorder = new DrawBorder();
|
|
} else if (mDrawBorder.isFrozen()) {
|
|
mDrawBorder = (DrawBorder) mDrawBorder.mutableCopy();
|
|
}
|
|
invalidate();
|
|
return mDrawBorder;
|
|
}
|
|
|
|
@Override
|
|
public boolean clipsSubviews() {
|
|
return mRemoveClippedSubviews;
|
|
}
|
|
}
|