mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Enable mix-blend-mode on ReactRootView so blending works with app background (#47336)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47336 Before mix-blend-mode would not blend with the background color due to it not being a ViewGroup. This adds the mix-blend-mode logic to ReactRootView so blending works Changelog: [Android][Fixed] - Enable mix-blend-mode on ReactRootView so blending works with app background Reviewed By: NickGerleman Differential Revision: D65156543 fbshipit-source-id: b3628b667573d0b56c74214e40d21c656fda495a
This commit is contained in:
committed by
Facebook GitHub Bot
parent
30e75a51f3
commit
24b0ded3cf
@@ -377,6 +377,7 @@ public class com/facebook/react/ReactRootView : android/widget/FrameLayout, com/
|
||||
protected fun dispatchJSPointerEvent (Landroid/view/MotionEvent;Z)V
|
||||
protected fun dispatchJSTouchEvent (Landroid/view/MotionEvent;)V
|
||||
public fun dispatchKeyEvent (Landroid/view/KeyEvent;)Z
|
||||
protected fun drawChild (Landroid/graphics/Canvas;Landroid/view/View;J)Z
|
||||
protected fun finalize ()V
|
||||
public fun getAppProperties ()Landroid/os/Bundle;
|
||||
public fun getCurrentReactContext ()Lcom/facebook/react/bridge/ReactContext;
|
||||
|
||||
+28
@@ -8,13 +8,16 @@
|
||||
package com.facebook.react;
|
||||
|
||||
import static com.facebook.infer.annotation.ThreadConfined.UI;
|
||||
import static com.facebook.react.uimanager.BlendModeHelper.needsIsolatedLayer;
|
||||
import static com.facebook.react.uimanager.common.UIManagerType.DEFAULT;
|
||||
import static com.facebook.react.uimanager.common.UIManagerType.FABRIC;
|
||||
import static com.facebook.systrace.Systrace.TRACE_TAG_REACT_JAVA_BRIDGE;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.BlendMode;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Insets;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Build;
|
||||
@@ -65,6 +68,7 @@ import com.facebook.react.uimanager.RootView;
|
||||
import com.facebook.react.uimanager.RootViewUtil;
|
||||
import com.facebook.react.uimanager.UIManagerHelper;
|
||||
import com.facebook.react.uimanager.common.UIManagerType;
|
||||
import com.facebook.react.uimanager.common.ViewUtil;
|
||||
import com.facebook.react.uimanager.events.EventDispatcher;
|
||||
import com.facebook.systrace.Systrace;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
@@ -290,6 +294,30 @@ public class ReactRootView extends FrameLayout implements RootView, ReactRoot {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
|
||||
|
||||
BlendMode mixBlendMode = null;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q
|
||||
&& ViewUtil.getUIManagerType(this) == UIManagerType.FABRIC
|
||||
&& needsIsolatedLayer(this)) {
|
||||
mixBlendMode = (BlendMode) child.getTag(R.id.mix_blend_mode);
|
||||
if (mixBlendMode != null) {
|
||||
Paint p = new Paint();
|
||||
p.setBlendMode(mixBlendMode);
|
||||
canvas.saveLayer(0, 0, getWidth(), getHeight(), p);
|
||||
}
|
||||
}
|
||||
|
||||
boolean result = super.drawChild(canvas, child, drawingTime);
|
||||
|
||||
if (mixBlendMode != null) {
|
||||
canvas.restore();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dispatchKeyEvent(KeyEvent ev) {
|
||||
if (!hasActiveReactContext() || !isViewAttachedToReactInstance()) {
|
||||
|
||||
+7
@@ -10,6 +10,9 @@ package com.facebook.react.uimanager
|
||||
import android.annotation.TargetApi
|
||||
import android.graphics.BlendMode
|
||||
import android.os.Build
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.view.children
|
||||
import com.facebook.react.R
|
||||
|
||||
@TargetApi(29)
|
||||
internal object BlendModeHelper {
|
||||
@@ -41,4 +44,8 @@ internal object BlendModeHelper {
|
||||
else -> throw IllegalArgumentException("Invalid mix-blend-mode name: $mixBlendMode")
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
public fun needsIsolatedLayer(view: ViewGroup): Boolean =
|
||||
view.children.any { it.getTag(R.id.mix_blend_mode) != null }
|
||||
}
|
||||
|
||||
+5
-13
@@ -37,6 +37,7 @@ import com.facebook.react.touch.OnInterceptTouchEventListener;
|
||||
import com.facebook.react.touch.ReactHitSlopView;
|
||||
import com.facebook.react.touch.ReactInterceptingViewGroup;
|
||||
import com.facebook.react.uimanager.BackgroundStyleApplicator;
|
||||
import com.facebook.react.uimanager.BlendModeHelper;
|
||||
import com.facebook.react.uimanager.LengthPercentage;
|
||||
import com.facebook.react.uimanager.LengthPercentageType;
|
||||
import com.facebook.react.uimanager.MeasureSpecAssertions;
|
||||
@@ -747,16 +748,6 @@ public class ReactViewGroup extends ViewGroup
|
||||
}
|
||||
}
|
||||
|
||||
private boolean needsIsolatedLayer() {
|
||||
for (int i = 0; i < getChildCount(); i++) {
|
||||
if (getChildAt(i).getTag(R.id.mix_blend_mode) != null) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Rect getHitSlopRect() {
|
||||
return mHitSlopRect;
|
||||
@@ -793,7 +784,7 @@ public class ReactViewGroup extends ViewGroup
|
||||
|
||||
@Override
|
||||
public void setOverflowInset(int left, int top, int right, int bottom) {
|
||||
if (needsIsolatedLayer()
|
||||
if (BlendModeHelper.needsIsolatedLayer(this)
|
||||
&& (mOverflowInset.left != left
|
||||
|| mOverflowInset.top != top
|
||||
|| mOverflowInset.right != right
|
||||
@@ -823,7 +814,7 @@ public class ReactViewGroup extends ViewGroup
|
||||
public void draw(Canvas canvas) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q
|
||||
&& ViewUtil.getUIManagerType(this) == UIManagerType.FABRIC
|
||||
&& needsIsolatedLayer()) {
|
||||
&& BlendModeHelper.needsIsolatedLayer(this)) {
|
||||
|
||||
// Check if the view is a stacking context and has children, if it does, do the rendering
|
||||
// offscreen and then composite back. This follows the idea of group isolation on blending
|
||||
@@ -859,7 +850,8 @@ public class ReactViewGroup extends ViewGroup
|
||||
}
|
||||
|
||||
BlendMode mixBlendMode = null;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && needsIsolatedLayer()) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q
|
||||
&& BlendModeHelper.needsIsolatedLayer(this)) {
|
||||
mixBlendMode = (BlendMode) child.getTag(R.id.mix_blend_mode);
|
||||
if (mixBlendMode != null) {
|
||||
Paint p = new Paint();
|
||||
|
||||
Reference in New Issue
Block a user