mirror of
https://github.com/zoriya/react-native-svg.git
synced 2026-06-02 06:35:04 +00:00
Allow nesting React-Native View components inside svg (Android, poc wip)
This commit is contained in:
@@ -96,6 +96,8 @@ class GroupShadowNode extends RenderableShadowNode {
|
||||
} else if (lNode instanceof SvgViewShadowNode) {
|
||||
SvgViewShadowNode svgView = (SvgViewShadowNode)lNode;
|
||||
svgView.drawChildren(canvas);
|
||||
} else {
|
||||
lNode.calculateLayout();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -16,22 +16,26 @@ import android.graphics.Point;
|
||||
import android.util.Log;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.facebook.react.ReactRootView;
|
||||
import com.facebook.react.bridge.ReactContext;
|
||||
import com.facebook.react.uimanager.LayoutShadowNode;
|
||||
import com.facebook.react.uimanager.ReactShadowNodeImpl;
|
||||
import com.facebook.react.uimanager.UIManagerModule;
|
||||
import com.facebook.react.uimanager.events.TouchEvent;
|
||||
import com.facebook.react.uimanager.events.TouchEventCoalescingKeyHelper;
|
||||
import com.facebook.react.uimanager.events.TouchEventType;
|
||||
import com.facebook.react.uimanager.events.EventDispatcher;
|
||||
import com.facebook.react.views.view.ReactViewGroup;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Custom {@link View} implementation that draws an RNSVGSvg React view and its \childrn.
|
||||
* Custom {@link View} implementation that draws an RNSVGSvg React view and its children.
|
||||
*/
|
||||
@SuppressLint("ViewConstructor")
|
||||
public class SvgView extends View {
|
||||
public class SvgView extends ViewGroup {
|
||||
public enum Events {
|
||||
@SuppressWarnings("unused")
|
||||
EVENT_DATA_URL("onDataURL");
|
||||
@@ -100,6 +104,30 @@ public class SvgView extends View {
|
||||
return super.dispatchTouchEvent(ev);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int l, int t, int r, int b) {
|
||||
for (int i = 0; i < this.getChildCount(); i++) {
|
||||
View child = this.getChildAt(i);
|
||||
if (child instanceof ReactViewGroup) {
|
||||
ReactShadowNodeImpl node = getShadowNode();
|
||||
for (int j = 0; j < node.getChildCount(); j++) {
|
||||
ReactShadowNodeImpl nodeChild = node.getChildAt(j);
|
||||
if (nodeChild.getReactTag() != child.getId()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
float x = nodeChild.getLayoutX();
|
||||
float y = nodeChild.getLayoutY();
|
||||
float nr = x + nodeChild.getLayoutWidth();
|
||||
float nb = y + nodeChild.getLayoutHeight();
|
||||
|
||||
child.layout(Math.round(x), Math.round(y), Math.round(nr), Math.round(nb));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int getAbsoluteLeft(View view) {
|
||||
int left = view.getLeft() - view.getScrollX();
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ package com.horcrux.svg;
|
||||
import android.graphics.Bitmap;
|
||||
import android.util.SparseArray;
|
||||
|
||||
import com.facebook.react.uimanager.ViewGroupManager;
|
||||
import com.facebook.yoga.YogaMeasureMode;
|
||||
import com.facebook.yoga.YogaMeasureFunction;
|
||||
import com.facebook.yoga.YogaNode;
|
||||
@@ -24,7 +25,7 @@ import javax.annotation.Nullable;
|
||||
* ViewManager for RNSVGSvgView React views. Renders as a {@link SvgView} and handles
|
||||
* invalidating the native view on shadow view updates happening in the underlying tree.
|
||||
*/
|
||||
class SvgViewManager extends BaseViewManager<SvgView, SvgViewShadowNode> {
|
||||
class SvgViewManager extends ViewGroupManager<SvgView> {
|
||||
|
||||
private static final String REACT_CLASS = "RNSVGSvgView";
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.Typeface;
|
||||
import android.util.Base64;
|
||||
import android.view.View;
|
||||
|
||||
import com.facebook.react.uimanager.DisplayMetricsHolder;
|
||||
import com.facebook.react.uimanager.LayoutShadowNode;
|
||||
@@ -110,7 +111,7 @@ public class SvgViewShadowNode extends LayoutShadowNode {
|
||||
|
||||
@Override
|
||||
public boolean isVirtualAnchor() {
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -185,6 +186,8 @@ public class SvgViewShadowNode extends LayoutShadowNode {
|
||||
if (node.isResponsible() && !mResponsible) {
|
||||
mResponsible = true;
|
||||
}
|
||||
} else {
|
||||
lNode.calculateLayout();
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -262,10 +265,6 @@ public class SvgViewShadowNode extends LayoutShadowNode {
|
||||
void traverseChildren(VirtualNode.NodeRunnable runner) {
|
||||
for (int i = 0; i < getChildCount(); i++) {
|
||||
ReactShadowNode child = getChildAt(i);
|
||||
if (!(child instanceof VirtualNode)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
runner.run((LayoutShadowNode) child);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,6 +64,7 @@ abstract class VirtualNode extends LayoutShadowNode {
|
||||
private GlyphContext glyphContext;
|
||||
|
||||
VirtualNode() {
|
||||
setIsLayoutOnly(true);
|
||||
mScale = DisplayMetricsHolder.getScreenDisplayMetrics().density;
|
||||
}
|
||||
|
||||
@@ -72,6 +73,11 @@ abstract class VirtualNode extends LayoutShadowNode {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVirtualAnchor() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
GroupShadowNode getTextRoot() {
|
||||
VirtualNode node = this;
|
||||
@@ -314,10 +320,6 @@ abstract class VirtualNode extends LayoutShadowNode {
|
||||
void traverseChildren(NodeRunnable runner) {
|
||||
for (int i = 0; i < getChildCount(); i++) {
|
||||
ReactShadowNode child = getChildAt(i);
|
||||
if (!(child instanceof VirtualNode) && !(child instanceof SvgViewShadowNode)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
runner.run((LayoutShadowNode) child);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user