[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();
final SvgViewShadowNode svg = getSvgShadowNode();
final GroupShadowNode self = this;
final RectF groupRect = new RectF();
traverseChildren(new NodeRunnable() {
public void run(ReactShadowNode lNode) {
if (lNode instanceof VirtualNode) {
@@ -79,6 +80,11 @@ class GroupShadowNode extends RenderableShadowNode {
int count = node.saveAndSetupCanvas(canvas);
node.draw(canvas, paint, opacity * mOpacity);
RectF r = node.getClientRect();
if (r != null) {
groupRect.union(r);
}
node.restoreCanvas(canvas, count);
if (node instanceof RenderableShadowNode) {
@@ -98,6 +104,7 @@ class GroupShadowNode extends RenderableShadowNode {
}
}
});
this.setClientRect(groupRect);
popGlyphContext();
}
@@ -11,6 +11,7 @@ package com.horcrux.svg;
import android.graphics.Canvas;
import android.graphics.DashPathEffect;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
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.ReadableArray;
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.events.EventDispatcher;
import java.lang.reflect.Field;
import java.util.ArrayList;
@@ -204,6 +208,13 @@ abstract public class RenderableShadowNode extends VirtualNode {
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);
if (setupFillPaint(paint, opacity * mFillOpacity)) {
@@ -28,6 +28,7 @@ import com.facebook.react.uimanager.annotations.ReactProp;
import java.io.ByteArrayOutputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Stack;
/**
* Shadow node for RNSVG virtual tree root - RNSVGSvgView
@@ -51,6 +52,9 @@ public class SvgViewShadowNode extends LayoutShadowNode {
private int mMeetOrSlice;
private Matrix mInvViewBoxMatrix = new Matrix();
private boolean mInvertible = true;
private Matrix initialCTM;
private Matrix invInitialCTM;
public SvgViewShadowNode() {
mScale = DisplayMetricsHolder.getScreenDisplayMetrics().density;
@@ -147,6 +151,9 @@ public class SvgViewShadowNode extends LayoutShadowNode {
void drawChildren(final Canvas canvas) {
mCanvas = canvas;
this.initialCTM = canvas.getMatrix();
this.invInitialCTM = new Matrix();
this.initialCTM.invert(this.invInitialCTM);
if (mAlign != null) {
RectF vbRect = getViewBox();
float width = getLayoutWidth();
@@ -277,4 +284,12 @@ public class SvgViewShadowNode extends LayoutShadowNode {
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);
}
this.setClientRect(template.getClientRect());
template.restoreCanvas(canvas, count);
if (template instanceof RenderableShadowNode) {
((RenderableShadowNode)template).resetProperties();
@@ -21,8 +21,11 @@ import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.common.ReactConstants;
import com.facebook.react.uimanager.DisplayMetricsHolder;
import com.facebook.react.uimanager.LayoutShadowNode;
import com.facebook.react.uimanager.OnLayoutEvent;
import com.facebook.react.uimanager.ReactShadowNode;
import com.facebook.react.uimanager.UIManagerModule;
import com.facebook.react.uimanager.annotations.ReactProp;
import com.facebook.react.uimanager.events.EventDispatcher;
import javax.annotation.Nullable;
@@ -47,6 +50,7 @@ abstract class VirtualNode extends LayoutShadowNode {
Matrix mMatrix = new Matrix();
Matrix mInvMatrix = new Matrix();
boolean mInvertible = true;
RectF mClientRect;
private int mClipRule;
private @Nullable String mClipPath;
@@ -345,4 +349,29 @@ abstract class VirtualNode extends LayoutShadowNode {
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;
}
}