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:
Denis Koroskin 2016-02-24 17:10:33 -08:00 committed by Ahmed El-Helw
parent c36d4593fd
commit 5305f3b68e
2 changed files with 30 additions and 9 deletions

View File

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

View File

@ -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()) {