Repository navigation
Android broken background with react-native 0.75.1 #226
Description
Activity
Same here
I tried changing the background color in different ways, but nothing helpedReacted by Martin and Muhammed Jasim Tk@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!
Reacted by Martin, Dembe, MikitaKliushun, Alexandr Kozhevnikov, Stathis Ntonas, wsmwason, Nikita Dudin, John Ferlito, Kirill Osintsev, Craig Martin and 17 more@maksim-v Thank you! you saved the day!!
Reacted by Maksim VarvashevichI 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
Reacted by Maksim Varvashevich, 박성준 and Zachary DiamondAnyone check if react-native-shimmer still broking?!
@maksim-v thanks, this was driving me crazy.
Reacted by Maksim Varvashevichcan 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
Reacted by p@v, kesha-antonov and Alessandro Marra- added a commit that references this issue
on Sep 11, 2024 Anyone available to approve the PRs fixing this bug?
Reacted by Zachary Diamond and Tom McIntosh`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?
#228 this merge will fix this issue. I've tested it
- added a commit that references this issue
on Nov 4, 2024 this works 👍. hope its fixed
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?