From 15b4ac63b93ac3f6b682de0f03f1822d90bcad34 Mon Sep 17 00:00:00 2001 From: Mikael Sand Date: Fri, 3 Jan 2020 20:17:21 +0200 Subject: [PATCH] feat(android): support using other native views in e.g. masks --- .../main/java/com/horcrux/svg/GroupView.java | 5 +++++ .../main/java/com/horcrux/svg/SvgView.java | 21 +++++++++++++++++++ .../java/com/horcrux/svg/VirtualView.java | 11 ++++++---- 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/android/src/main/java/com/horcrux/svg/GroupView.java b/android/src/main/java/com/horcrux/svg/GroupView.java index ab2b9ba9..83bae378 100644 --- a/android/src/main/java/com/horcrux/svg/GroupView.java +++ b/android/src/main/java/com/horcrux/svg/GroupView.java @@ -23,6 +23,7 @@ import android.view.View; import com.facebook.react.bridge.ReactContext; import com.facebook.react.bridge.ReadableMap; import com.facebook.react.uimanager.annotations.ReactProp; +import com.facebook.react.views.view.ReactViewGroup; import javax.annotation.Nullable; @@ -123,6 +124,10 @@ class GroupView extends RenderableView { if (svgView.isResponsible()) { svg.enableTouchEvents(); } + } else if (child instanceof ReactViewGroup) { + // Enable rendering other native ancestor views in e.g. masks + ReactViewGroup vg = (ReactViewGroup) child; + vg.draw(canvas); } } this.setClientRect(groupRect); diff --git a/android/src/main/java/com/horcrux/svg/SvgView.java b/android/src/main/java/com/horcrux/svg/SvgView.java index 554d3a14..d045456e 100644 --- a/android/src/main/java/com/horcrux/svg/SvgView.java +++ b/android/src/main/java/com/horcrux/svg/SvgView.java @@ -21,6 +21,8 @@ import android.util.Base64; import android.view.View; import android.view.ViewParent; +import androidx.annotation.NonNull; + import com.facebook.react.bridge.Dynamic; import com.facebook.react.bridge.ReactContext; import com.facebook.react.uimanager.DisplayMetricsHolder; @@ -94,6 +96,25 @@ public class SvgView extends ReactViewGroup implements ReactCompoundView, ReactC mBitmap = null; } + // Enable rendering other native ancestor views in e.g. masks, but don't render them another time + Bitmap fakeBitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888); + Canvas fake = new Canvas(fakeBitmap); + + @Override + protected void dispatchDraw(Canvas canvas) { + super.dispatchDraw(fake); + } + + protected boolean drawChild(Canvas canvas, View child, long drawingTime) { + return super.drawChild(fake, child, drawingTime); + } + + @Override + public void onDescendantInvalidated(@NonNull View child, @NonNull View target) { + super.onDescendantInvalidated(child, target); + invalidate(); + } + @Override protected void onDraw(Canvas canvas) { if (getParent() instanceof VirtualView) { diff --git a/android/src/main/java/com/horcrux/svg/VirtualView.java b/android/src/main/java/com/horcrux/svg/VirtualView.java index 0c2e4b85..bc1f4019 100644 --- a/android/src/main/java/com/horcrux/svg/VirtualView.java +++ b/android/src/main/java/com/horcrux/svg/VirtualView.java @@ -559,13 +559,17 @@ abstract public class VirtualView extends ReactViewGroup { return; } mClientRect = rect; - if (mClientRect == null || (!mResponsible && !mOnLayout)) { + if (mClientRect == null) { + return; + } + int width = (int) Math.ceil(mClientRect.width()); + int height = (int) Math.ceil(mClientRect.height()); + setMeasuredDimension(width, height); + if ((!mResponsible && !mOnLayout)) { return; } int left = (int) Math.floor(mClientRect.left); int top = (int) Math.floor(mClientRect.top); - int width = (int) Math.ceil(mClientRect.width()); - int height = (int) Math.ceil(mClientRect.height()); if (mResponsible) { int right = (int) Math.ceil(mClientRect.right); int bottom = (int) Math.ceil(mClientRect.bottom); @@ -576,7 +580,6 @@ abstract public class VirtualView extends ReactViewGroup { setRight(right); setBottom(bottom); } - setMeasuredDimension(width, height); } if (mOnLayout) { EventDispatcher eventDispatcher = mContext