[android] fire onLayout

This commit is contained in:
Maksym Komarychev
2018-04-13 22:32:49 +03:00
parent 4fc6f4fd87
commit ba7bef6ce8
5 changed files with 64 additions and 0 deletions
@@ -69,6 +69,7 @@ class GroupShadowNode extends RenderableShadowNode {
pushGlyphContext(); pushGlyphContext();
final SvgViewShadowNode svg = getSvgShadowNode(); final SvgViewShadowNode svg = getSvgShadowNode();
final GroupShadowNode self = this; final GroupShadowNode self = this;
final RectF groupRect = new RectF();
traverseChildren(new NodeRunnable() { traverseChildren(new NodeRunnable() {
public void run(ReactShadowNode lNode) { public void run(ReactShadowNode lNode) {
if (lNode instanceof VirtualNode) { if (lNode instanceof VirtualNode) {
@@ -79,6 +80,11 @@ class GroupShadowNode extends RenderableShadowNode {
int count = node.saveAndSetupCanvas(canvas); int count = node.saveAndSetupCanvas(canvas);
node.draw(canvas, paint, opacity * mOpacity); node.draw(canvas, paint, opacity * mOpacity);
RectF r = node.getClientRect();
if (r != null) {
groupRect.union(r);
}
node.restoreCanvas(canvas, count); node.restoreCanvas(canvas, count);
if (node instanceof RenderableShadowNode) { if (node instanceof RenderableShadowNode) {
@@ -98,6 +104,7 @@ class GroupShadowNode extends RenderableShadowNode {
} }
} }
}); });
this.setClientRect(groupRect);
popGlyphContext(); popGlyphContext();
} }
@@ -11,6 +11,7 @@ package com.horcrux.svg;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.DashPathEffect; import android.graphics.DashPathEffect;
import android.graphics.Matrix;
import android.graphics.Paint; import android.graphics.Paint;
import android.graphics.Path; import android.graphics.Path;
import android.graphics.RectF; import android.graphics.RectF;
@@ -20,7 +21,10 @@ import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.JSApplicationIllegalArgumentException; import com.facebook.react.bridge.JSApplicationIllegalArgumentException;
import com.facebook.react.bridge.ReadableArray; import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.WritableArray; import com.facebook.react.bridge.WritableArray;
import com.facebook.react.uimanager.OnLayoutEvent;
import com.facebook.react.uimanager.UIManagerModule;
import com.facebook.react.uimanager.annotations.ReactProp; import com.facebook.react.uimanager.annotations.ReactProp;
import com.facebook.react.uimanager.events.EventDispatcher;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.ArrayList; import java.util.ArrayList;
@@ -204,6 +208,13 @@ abstract public class RenderableShadowNode extends VirtualNode {
mPath.setFillType(mFillRule); mPath.setFillType(mFillRule);
} }
RectF clientRect = new RectF();
mPath.computeBounds(clientRect, true);
Matrix svgToViewMatrix = new Matrix(canvas.getMatrix());
svgToViewMatrix.preConcat(this.getSvgShadowNode().getInvInitialCTM());
svgToViewMatrix.mapRect(clientRect);
this.setClientRect(clientRect);
clip(canvas, paint); clip(canvas, paint);
if (setupFillPaint(paint, opacity * mFillOpacity)) { if (setupFillPaint(paint, opacity * mFillOpacity)) {
@@ -28,6 +28,7 @@ import com.facebook.react.uimanager.annotations.ReactProp;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Stack;
/** /**
* Shadow node for RNSVG virtual tree root - RNSVGSvgView * Shadow node for RNSVG virtual tree root - RNSVGSvgView
@@ -51,6 +52,9 @@ public class SvgViewShadowNode extends LayoutShadowNode {
private int mMeetOrSlice; private int mMeetOrSlice;
private Matrix mInvViewBoxMatrix = new Matrix(); private Matrix mInvViewBoxMatrix = new Matrix();
private boolean mInvertible = true; private boolean mInvertible = true;
private Matrix initialCTM;
private Matrix invInitialCTM;
public SvgViewShadowNode() { public SvgViewShadowNode() {
mScale = DisplayMetricsHolder.getScreenDisplayMetrics().density; mScale = DisplayMetricsHolder.getScreenDisplayMetrics().density;
@@ -147,6 +151,9 @@ public class SvgViewShadowNode extends LayoutShadowNode {
void drawChildren(final Canvas canvas) { void drawChildren(final Canvas canvas) {
mCanvas = canvas; mCanvas = canvas;
this.initialCTM = canvas.getMatrix();
this.invInitialCTM = new Matrix();
this.initialCTM.invert(this.invInitialCTM);
if (mAlign != null) { if (mAlign != null) {
RectF vbRect = getViewBox(); RectF vbRect = getViewBox();
float width = getLayoutWidth(); float width = getLayoutWidth();
@@ -277,4 +284,12 @@ public class SvgViewShadowNode extends LayoutShadowNode {
runner.run(child); runner.run(child);
} }
} }
public Matrix getInitialCTM() {
return this.initialCTM;
}
public Matrix getInvInitialCTM() {
return this.invInitialCTM;
}
} }
@@ -63,6 +63,8 @@ class UseShadowNode extends RenderableShadowNode {
template.draw(canvas, paint, opacity * mOpacity); template.draw(canvas, paint, opacity * mOpacity);
} }
this.setClientRect(template.getClientRect());
template.restoreCanvas(canvas, count); template.restoreCanvas(canvas, count);
if (template instanceof RenderableShadowNode) { if (template instanceof RenderableShadowNode) {
((RenderableShadowNode)template).resetProperties(); ((RenderableShadowNode)template).resetProperties();
@@ -21,8 +21,11 @@ import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.common.ReactConstants; import com.facebook.react.common.ReactConstants;
import com.facebook.react.uimanager.DisplayMetricsHolder; import com.facebook.react.uimanager.DisplayMetricsHolder;
import com.facebook.react.uimanager.LayoutShadowNode; import com.facebook.react.uimanager.LayoutShadowNode;
import com.facebook.react.uimanager.OnLayoutEvent;
import com.facebook.react.uimanager.ReactShadowNode; import com.facebook.react.uimanager.ReactShadowNode;
import com.facebook.react.uimanager.UIManagerModule;
import com.facebook.react.uimanager.annotations.ReactProp; import com.facebook.react.uimanager.annotations.ReactProp;
import com.facebook.react.uimanager.events.EventDispatcher;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@@ -47,6 +50,7 @@ abstract class VirtualNode extends LayoutShadowNode {
Matrix mMatrix = new Matrix(); Matrix mMatrix = new Matrix();
Matrix mInvMatrix = new Matrix(); Matrix mInvMatrix = new Matrix();
boolean mInvertible = true; boolean mInvertible = true;
RectF mClientRect;
private int mClipRule; private int mClipRule;
private @Nullable String mClipPath; private @Nullable String mClipPath;
@@ -345,4 +349,29 @@ abstract class VirtualNode extends LayoutShadowNode {
runner.run(child); runner.run(child);
} }
} }
void setClientRect(RectF rect) {
if (mClientRect != null && mClientRect.equals(rect)) {
return;
}
mClientRect = rect;
if (mClientRect == null) {
return;
}
EventDispatcher eventDispatcher = this.getThemedContext()
.getNativeModule(UIManagerModule.class)
.getEventDispatcher();
eventDispatcher.dispatchEvent(OnLayoutEvent.obtain(
this.getReactTag(),
(int) mClientRect.left,
(int) mClientRect.top,
(int) mClientRect.width(),
(int) mClientRect.height()
));
}
public RectF getClientRect() {
return mClientRect;
}
} }