Fix OnLayoutEvent dispatching wrong x/y coordinates
Summary: OnLayoutEvent was incorrectly dispatching x/y coordinates relative to native View instead of relative to parent. This was causing issues in many cases, such as when Node was mounting to a View, in which case x/y would always be 0. This diff is fixing it. This diff also caches last OnLayoutEvent to avoid dispatching the event on every layout even when layout didn't chance. Reviewed By: ahmedre Differential Revision: D2955087
This commit is contained in:
parent
c36d4593fd
commit
5305f3b68e
|
@ -12,10 +12,11 @@ package com.facebook.react.flat;
|
|||
import javax.annotation.Nullable;
|
||||
|
||||
import com.facebook.infer.annotation.Assertions;
|
||||
import com.facebook.react.uimanager.ReactStylesDiffMap;
|
||||
import com.facebook.react.uimanager.LayoutShadowNode;
|
||||
import com.facebook.react.uimanager.annotations.ReactProp;
|
||||
import com.facebook.react.uimanager.OnLayoutEvent;
|
||||
import com.facebook.react.uimanager.ReactStylesDiffMap;
|
||||
import com.facebook.react.uimanager.ViewProps;
|
||||
import com.facebook.react.uimanager.annotations.ReactProp;
|
||||
|
||||
/**
|
||||
* FlatShadowNode is a base class for all shadow node used in FlatUIImplementation. It extends
|
||||
|
@ -50,6 +51,12 @@ import com.facebook.react.uimanager.ViewProps;
|
|||
private int mMoveToIndexInParent;
|
||||
private boolean mClipToBounds = false;
|
||||
|
||||
// last OnLayoutEvent info, only used when shouldNotifyOnLayout() is true.
|
||||
private int mLayoutX;
|
||||
private int mLayoutY;
|
||||
private int mLayoutWidth;
|
||||
private int mLayoutHeight;
|
||||
|
||||
/* package */ void handleUpdateProperties(ReactStylesDiffMap styles) {
|
||||
if (!mountsToView()) {
|
||||
// Make sure we mount this FlatShadowNode to a View if any of these properties are present.
|
||||
|
@ -277,6 +284,19 @@ import com.facebook.react.uimanager.ViewProps;
|
|||
return mDrawView;
|
||||
}
|
||||
|
||||
/* package */ final OnLayoutEvent obtainLayoutEvent(int x, int y, int width, int height) {
|
||||
if (mLayoutX == x && mLayoutY == y && mLayoutWidth == width && mLayoutHeight == height) {
|
||||
return null;
|
||||
}
|
||||
|
||||
mLayoutX = x;
|
||||
mLayoutY = y;
|
||||
mLayoutWidth = width;
|
||||
mLayoutHeight = height;
|
||||
|
||||
return OnLayoutEvent.obtain(getReactTag(), x, y, width, height);
|
||||
}
|
||||
|
||||
/* package */ final boolean mountsToView() {
|
||||
return mDrawView != null;
|
||||
}
|
||||
|
|
|
@ -401,13 +401,14 @@ import com.facebook.react.uimanager.events.EventDispatcher;
|
|||
|
||||
// notify JS about layout event if requested
|
||||
if (node.shouldNotifyOnLayout()) {
|
||||
mOnLayoutEvents.add(
|
||||
OnLayoutEvent.obtain(
|
||||
node.getReactTag(),
|
||||
(int) roundedLeft,
|
||||
(int) roundedTop,
|
||||
(int) (roundedRight - roundedLeft),
|
||||
(int) (roundedBottom - roundedTop)));
|
||||
OnLayoutEvent layoutEvent = node.obtainLayoutEvent(
|
||||
Math.round(node.getLayoutX()),
|
||||
Math.round(node.getLayoutY()),
|
||||
(int) (roundedRight - roundedLeft),
|
||||
(int) (roundedBottom - roundedTop));
|
||||
if (layoutEvent != null) {
|
||||
mOnLayoutEvents.add(layoutEvent);
|
||||
}
|
||||
}
|
||||
|
||||
if (node.clipToBounds()) {
|
||||
|
|
Loading…
Reference in New Issue