Open MartinInAction opened 2 months ago
Same here I tried changing the background color in different ways, but nothing helped
@MartinInAction I found a temporary solution in case you are using hardware rendering mode. I haven't tested it with software mode. You just need to apply this patch:
diff --git a/node_modules/@react-native-masked-view/masked-view/android/src/main/java/org/reactnative/maskedview/RNCMaskedView.java b/node_modules/@react-native-masked-view/masked-view/android/src/main/java/org/reactnative/maskedview/RNCMaskedView.java
index 2ea0c5e..e8877e0 100644
--- a/node_modules/@react-native-masked-view/masked-view/android/src/main/java/org/reactnative/maskedview/RNCMaskedView.java
+++ b/node_modules/@react-native-masked-view/masked-view/android/src/main/java/org/reactnative/maskedview/RNCMaskedView.java
@@ -41,6 +41,7 @@ public class RNCMaskedView extends ReactViewGroup {
// draw the mask
if (mBitmapMask != null) {
+ setLayerType(LAYER_TYPE_HARDWARE, mPaint);
mPaint.setXfermode(mPorterDuffXferMode);
canvas.drawBitmap(mBitmapMask, 0, 0, mPaint);
mPaint.setXfermode(null);
Here I simply set the layer type in the dispatchDraw method, providing a Paint instance that controls how the layer is drawn on the screen. Here is the complete method:
@Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
if (mBitmapMaskInvalidated) {
// redraw mask element to support animated elements
updateBitmapMask();
mBitmapMaskInvalidated = false;
}
// draw the mask
if (mBitmapMask != null) {
setLayerType(LAYER_TYPE_HARDWARE, mPaint);
mPaint.setXfermode(mPorterDuffXferMode);
canvas.drawBitmap(mBitmapMask, 0, 0, mPaint);
mPaint.setXfermode(null);
}
}
Hope this helps!
@maksim-v Thank you! you saved the day!!
I tried this but still, react-native-shimmer and react-native-skelton view has same issue
@jasimchz are you sure the patch is applied?
@MartinInAction I found a temporary solution in case you are using hardware rendering mode. I haven't tested it with software mode. You just need to apply this patch:
diff --git a/node_modules/@react-native-masked-view/masked-view/android/src/main/java/org/reactnative/maskedview/RNCMaskedView.java b/node_modules/@react-native-masked-view/masked-view/android/src/main/java/org/reactnative/maskedview/RNCMaskedView.java index 2ea0c5e..e8877e0 100644 --- a/node_modules/@react-native-masked-view/masked-view/android/src/main/java/org/reactnative/maskedview/RNCMaskedView.java +++ b/node_modules/@react-native-masked-view/masked-view/android/src/main/java/org/reactnative/maskedview/RNCMaskedView.java @@ -41,6 +41,7 @@ public class RNCMaskedView extends ReactViewGroup { // draw the mask if (mBitmapMask != null) { + setLayerType(LAYER_TYPE_HARDWARE, mPaint); mPaint.setXfermode(mPorterDuffXferMode); canvas.drawBitmap(mBitmapMask, 0, 0, mPaint); mPaint.setXfermode(null);
Here I simply set the layer type in the dispatchDraw method, providing a Paint instance that controls how the layer is drawn on the screen. Here is the complete method:
@Override protected void dispatchDraw(Canvas canvas) { super.dispatchDraw(canvas); if (mBitmapMaskInvalidated) { // redraw mask element to support animated elements updateBitmapMask(); mBitmapMaskInvalidated = false; } // draw the mask if (mBitmapMask != null) { setLayerType(LAYER_TYPE_HARDWARE, mPaint); mPaint.setXfermode(mPorterDuffXferMode); canvas.drawBitmap(mBitmapMask, 0, 0, mPaint); mPaint.setXfermode(null); } }
Hope this helps!
Worked like a charm
Anyone check if react-native-shimmer still broking?!
@maksim-v thanks, this was driving me crazy.
can confirm this works with software mode rendering mode as well. tysm!
fyi the filename for the patch using patch-package is patches/@react-native-masked-view+masked-view+0.3.1.patch
Anyone available to approve the PRs fixing this bug?
`package org.reactnative.maskedview;
import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.PorterDuff; import android.graphics.PorterDuffXfermode; import android.view.View;
import com.facebook.react.views.view.ReactViewGroup;
public class RNCMaskedView extends ReactViewGroup { private static final String TAG = "RNCMaskedView";
private Bitmap mBitmapMask = null; private boolean mBitmapMaskInvalidated = false; private Paint mPaint; private PorterDuffXfermode mPorterDuffXferMode;
public RNCMaskedView(Context context) { super(context);
// Default to hardware rendering, androidRenderingMode prop will override
setRenderingMode("hardware");
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPorterDuffXferMode = new PorterDuffXfermode(PorterDuff.Mode.DST_IN);
}
@Override protected void dispatchDraw(Canvas canvas) { super.dispatchDraw(canvas);
if (mBitmapMaskInvalidated) {
// redraw mask element to support animated elements
updateBitmapMask();
mBitmapMaskInvalidated = false;
}
// draw the mask
if (mBitmapMask != null) {
setLayerType(LAYER_TYPE_HARDWARE, mPaint);
mPaint.setXfermode(mPorterDuffXferMode);
canvas.drawBitmap(mBitmapMask, 0, 0, mPaint);
mPaint.setXfermode(null);
}
}
@Override public void onDescendantInvalidated(View child, View target) { super.onDescendantInvalidated(child, target);
if (!mBitmapMaskInvalidated) {
View maskView = getChildAt(0);
if (maskView != null) {
if (maskView.equals(child)) {
mBitmapMaskInvalidated = true;
}
}
}
invalidate();
}
@Override protected void onLayout(boolean changed, int l, int t, int r, int b) { super.onLayout(changed, l, t, r, b);
if (changed) {
mBitmapMaskInvalidated = true;
}
}
@Override protected void onAttachedToWindow() { super.onAttachedToWindow(); mBitmapMaskInvalidated = true; }
private void updateBitmapMask() { View maskView = getChildAt(0); if (maskView != null) { maskView.setVisibility(View.VISIBLE); if (this.mBitmapMask != null) { this.mBitmapMask.recycle(); } this.mBitmapMask = getBitmapFromView(maskView); maskView.setVisibility(View.INVISIBLE); } }
public static Bitmap getBitmapFromView(final View view) { view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
if (view.getMeasuredWidth() <= 0 || view.getMeasuredHeight() <= 0) {
return null;
}
final Bitmap bitmap = Bitmap.createBitmap(view.getMeasuredWidth(),
view.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
final Canvas canvas = new Canvas(bitmap);
view.draw(canvas);
return bitmap;
}
public void setRenderingMode(String renderingMode) { if (renderingMode.equals("software")) { setLayerType(LAYER_TYPE_SOFTWARE, null); } else { setLayerType(LAYER_TYPE_HARDWARE, null); } } } `
if any one want full file code there it is just copy and change RNCMaskedView.java file
@MartinInAction I found a temporary solution in case you are using hardware rendering mode. I haven't tested it with software mode. You just need to apply this patch:
diff --git a/node_modules/@react-native-masked-view/masked-view/android/src/main/java/org/reactnative/maskedview/RNCMaskedView.java b/node_modules/@react-native-masked-view/masked-view/android/src/main/java/org/reactnative/maskedview/RNCMaskedView.java index 2ea0c5e..e8877e0 100644 --- a/node_modules/@react-native-masked-view/masked-view/android/src/main/java/org/reactnative/maskedview/RNCMaskedView.java +++ b/node_modules/@react-native-masked-view/masked-view/android/src/main/java/org/reactnative/maskedview/RNCMaskedView.java @@ -41,6 +41,7 @@ public class RNCMaskedView extends ReactViewGroup { // draw the mask if (mBitmapMask != null) { + setLayerType(LAYER_TYPE_HARDWARE, mPaint); mPaint.setXfermode(mPorterDuffXferMode); canvas.drawBitmap(mBitmapMask, 0, 0, mPaint); mPaint.setXfermode(null);
Here I simply set the layer type in the dispatchDraw method, providing a Paint instance that controls how the layer is drawn on the screen. Here is the complete method:
@Override protected void dispatchDraw(Canvas canvas) { super.dispatchDraw(canvas); if (mBitmapMaskInvalidated) { // redraw mask element to support animated elements updateBitmapMask(); mBitmapMaskInvalidated = false; } // draw the mask if (mBitmapMask != null) { setLayerType(LAYER_TYPE_HARDWARE, mPaint); mPaint.setXfermode(mPorterDuffXferMode); canvas.drawBitmap(mBitmapMask, 0, 0, mPaint); mPaint.setXfermode(null); } }
Hope this helps!
This patch does solve the Problem on Android, however on slow/old devices it freezes the app for some seconds and causes some really bad hangs/delays (using masked view in an animation). Has anyone experiences something similar with this fix?
Left is android sim and right is iOS. I cant get rid of the black background on android since upgrading to RN 0.75.1. Prior versions worked great!!
Any ideas on how to fix this?